Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Benoit Viguier
coq-verif-tweetnacl
Commits
e3e5ff3d
Commit
e3e5ff3d
authored
Jul 29, 2019
by
Benoit Viguier
Browse files
packaging
parent
f5059abf
Changes
16
Expand all
Hide whitespace changes
Inline
Side-by-side
.gitignore
View file @
e3e5ff3d
...
...
@@ -38,7 +38,8 @@ Doc
usenix*
.coqdeps.d
Makefile.conf
Makefile
proofs/*/Makefile
.dist
# Created by https://www.gitignore.io/api/latex,c++,coq,c,ocaml,sublimetext,vim,emacs
...
...
@@ -79,6 +80,7 @@ Makefile
*.vrb
*.xdy
*.tdo
coq-verif-tweetnacl*
### C++ ###
# Compiled Object files
...
...
Makefile
0 → 100644
View file @
e3e5ff3d
DIST
=
coq-verif-tweetnacl
all
:
coq-tweetnacl-spec coq-tweetnacl-vst
readme
:
less README.md
# DEFINE GENERIC ROUTINES (hidden via . prefix)
.configure1 .configure2
:
cd
$P
&&
$(SHELL)
configure.sh
.building1 .building2
:
cd
$P
&&
$(MAKE)
-j
cd
$P
&&
$(MAKE)
install
.dusting1 .dusting2
:
cd
$P
&&
$(MAKE)
clean
cd
$P
&&
rm
_CoqProject
cd
$P
&&
rm
Makefile
cd
$P
&&
rm
Makefile.conf
# DEFINE REAL TARGETS
coq-tweetnacl-spec
:
P=proofs/spec
coq-tweetnacl-spec
:
.configure1 .building1
clean-spec
:
P=proofs/spec
clean-spec
:
.configure1 .dusting1
coq-tweetnacl-vst
:
P=proofs/vst
coq-tweetnacl-vst
:
coq-tweetnacl-spec .configure2 .building2
clean-vst
:
P=proofs/vst
clean-vst
:
.configure2 .dusting2
clean
:
clean-spec clean-vst clean-dist
# build paper
paper
:
cd
paper
&&
$(MAKE)
clean-paper
:
cd
paper
&&
$(MAKE)
clean
# generate artefact
$(DIST)
:
mkdir
$(DIST)
dist
:
$(DIST)
cp
-r
proofs
$(DIST)
mkdir
$(DIST)
/packages
cp
-r
packages/coq-compcert
$(DIST)
/packages/
cp
-r
packages/coq-reciprocity
$(DIST)
/packages/
cp
-r
packages/coq-ssr-elliptic-curves
$(DIST)
/packages/
cp
-r
packages/coq-vst
$(DIST)
/packages/
cp
repo
$(DIST)
/
cp
version
$(DIST)
/
cp
README.md
$(DIST)
/
cp
Makefile
$(DIST)
/
tar
-czvf
$(DIST)
.tar.gz
$(DIST)
clean-dist
:
$(DIST)
rm
-r
$(DIST)
-
rm
$(DIST)
.tar.gz
README.md
View file @
e3e5ff3d
...
...
@@ -39,14 +39,7 @@ opam repo add coq-extra-dev https://coq.inria.fr/opam/extra-dev
### 4. Set up project related dependencies (dependencies at specific commit number.)
Add the repository by using the address:
```
bash
opam repo add tweetnacl git://gitlab.science.ru.nl/benoit/tweetnacl/
```
Or by cloning it:
```
bash
git clone https://gitlab.science.ru.nl/benoit/tweetnacl/ coq-verif-tweetnacl
cd
coq-verif-tweetnacl
opam repo add tweetnacl .
```
...
...
@@ -55,12 +48,18 @@ opam repo add tweetnacl .
```
bash
opam update
# if you want coqide
# if you want coqide
(may require additional dependencies)
opam
install
coqide.8.8.2
```
Pin the current repository as an opam to be able to fetch the dependencies
```
bash
opam pin add
-n
coq-verif-tweetnacl
.
# install dependencies
opam
install
--deps-only
coq-verif-tweetnacl
```
### 6. Install the full Verification
Everything is compiled the following command:
...
...
@@ -71,12 +70,6 @@ opam install coq-verif-tweetnacl
However if you want to compile each part you can follow these steps:
Clone the repository:
```
bash
git clone https://gitlab.science.ru.nl/benoit/tweetnacl/ coq-verif-tweetnacl
cd
coq-verif-tweetnacl
```
##### 6.1 Install TweetNacl Mathematical Model and Specification
To compile manually:
...
...
@@ -122,7 +115,7 @@ opam install coq-tweetnacl-vst
### Benchmarks
```
```
bash
▶
time
opam
install
coq-verif-tweetnacl
The following actions will be performed:
∗
install
camlp5 7.06.10-g84ce6cc4
[
required by coq]
...
...
makefile
deleted
100644 → 0
View file @
f5059abf
all
:
coq-tweetnacl-spec coq-tweetnacl-vst
coq-tweetnacl-spec
:
cd
proofs/spec
;
\
./configure.sh
;
\
$(MAKE)
-j
;
\
$(MAKE)
install
coq-tweetnacl-vst
:
coq-tweetnacl-spec
cd
proofs/vst
;
\
./configure.sh
;
\
$(MAKE)
-j
;
\
$(MAKE)
install
packages/coq-tweetnacl-spec/coq-tweetnacl-spec.dev/
opam
→
opam
View file @
e3e5ff3d
opam-version: "2.0"
name: "coq-tweetnacl
-spec
"
name: "coq-
verif-
tweetnacl"
maintainer: "benoit@cs.ru.nl"
homepage: "https://gitlab.science.ru.nl/benoit/tweetnacl/"
license: "MIT"
build: [
["./configure.sh"]
[make "-j%{jobs}%"]
]
build: []
install: [
[make "
inst
all"]
[make "
-j%{jobs}%" "
all"]
]
remove: [
"rm" "-R" "%{lib}%/coq/user-contrib/Tweetnacl"
]
remove: []
depends: [
"coq" {>= "8.7.0" & < "8.9"}
"coq-coqprime" {= "1.0.3"}
...
...
@@ -19,14 +16,14 @@ depends: [
"coq-mathcomp-multinomials"
"coq-mathcomp-ssreflect" {= "1.7.0"}
"coq-reciprocity"
"coq-vst" {= "2.0"}
]
author: [
"benoit@cs.ru.nl"
"timmy@timmyweerwag.nl"
]
description: """
Verifying the Tweet
nac
l implementation
: Specification
Verifying the Tweet
NaC
l implementation
"""
url {
src: "git+https://git
hub.com/ildyria/coq-tweetnacl-verif/tree/master/proofs/spec
"
src: "git+https://git
lab.science.ru.nl/benoit/tweetnacl/
"
}
packages/coq-reciprocity/coq-reciprocity.dev/opam
View file @
e3e5ff3d
...
...
@@ -22,5 +22,5 @@ description:"""
Various proofs in Coq. As of now, only contains the proof of the theorem of quadratic reciprocity.
"""
url {
src: "git+https://github.com/ildyria/coq-proofs.git"
src: "git+https://github.com/ildyria/coq-proofs.git
#fork
"
}
packages/coq-tweetnacl-vst/coq-tweetnacl-vst.dev/opam
deleted
100644 → 0
View file @
f5059abf
opam-version: "2.0"
name: "coq-tweetnacl-vst"
maintainer: "benoit@cs.ru.nl"
homepage: "https://gitlab.science.ru.nl/benoit/tweetnacl/"
license: "MIT"
build: [
["./configure.sh"]
[make "-j%{jobs}%"]
]
install: [
[make "install"]
]
remove: ["rm" "-R" "%{lib}%/coq/user-contrib/Tweetnacl_verif"]
depends: [
"coq" {>= "8.7.0" & < "8.9"}
"coq-coqprime" {= "1.0.3"}
"coq-stdpp" {= "1.1.0"}
"coq-ssr-elliptic-curves"
"coq-mathcomp-ssreflect"
"coq-vst" {= "2.0"}
"coq-tweetnacl-spec"
]
author: [
"benoit@cs.ru.nl"
]
description: """
Verifying the Tweetnacl implementation: VST
"""
url {
src: "git+https://github.com/ildyria/coq-tweetnacl-verif/master/tree/proofs/vst"
}
packages/coq-verif-tweetnacl/coq-verif-tweetnacl.dev/opam
View file @
e3e5ff3d
opam-version: "2.0"
name: "coq-tweetnacl
-verif
"
name: "coq-
verif-
tweetnacl"
maintainer: "benoit@cs.ru.nl"
homepage: "https://gitlab.science.ru.nl/benoit/tweetnacl/"
license: "MIT"
...
...
@@ -22,7 +22,7 @@ author: [
"benoit@cs.ru.nl"
]
description: """
Verifying the Tweet
nac
l implementation
Verifying the Tweet
NaC
l implementation
"""
url {
src: "git+https://gitlab.science.ru.nl/benoit/tweetnacl/"
...
...
proofs/spec/C/break.c
deleted
100755 → 0
View file @
f5059abf
#include <stdio.h>
#include <stdbool.h>
typedef
long
long
i64
;
typedef
i64
gf
[
16
];
#define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c"
#define BYTE_TO_BINARY(byte) \
(byte & 0x80 ? '1' : '0'), \
(byte & 0x40 ? '1' : '0'), \
(byte & 0x20 ? '1' : '0'), \
(byte & 0x10 ? '1' : '0'), \
(byte & 0x08 ? '1' : '0'), \
(byte & 0x04 ? '1' : '0'), \
(byte & 0x02 ? '1' : '0'), \
(byte & 0x01 ? '1' : '0')
static
void
print_bin64
(
i64
val
)
{
printf
(
" "
BYTE_TO_BINARY_PATTERN
" "
BYTE_TO_BINARY_PATTERN
" "
BYTE_TO_BINARY_PATTERN
" "
BYTE_TO_BINARY_PATTERN
,
BYTE_TO_BINARY
(
val
>>
56
),
BYTE_TO_BINARY
(
val
>>
48
),
BYTE_TO_BINARY
(
val
>>
40
),
BYTE_TO_BINARY
(
val
>>
32
));
printf
(
" "
BYTE_TO_BINARY_PATTERN
" "
BYTE_TO_BINARY_PATTERN
" "
BYTE_TO_BINARY_PATTERN
" "
BYTE_TO_BINARY_PATTERN
,
BYTE_TO_BINARY
(
val
>>
24
),
BYTE_TO_BINARY
(
val
>>
16
),
BYTE_TO_BINARY
(
val
>>
8
),
BYTE_TO_BINARY
(
val
));
printf
(
"
\n
"
);
}
static
void
print_o
(
gf
o
)
{
for
(
int
j
=
0
;
j
<
16
;
++
j
)
{
printf
(
"%2i: "
,
j
);
print_bin64
(
o
[
j
]);
}
}
static
void
car25519
(
gf
o
,
bool
b
)
{
int
i
;
i64
c
;
for
(
i
=
0
;
i
<
16
;
++
i
)
{
// o[i]+=(1LL<<16);
c
=
o
[
i
]
>>
16
;
// o[(i+1)*(i<15)]+=c-1+37*(c-1)*(i==15);
o
[(
i
+
1
)
*
(
i
<
15
)]
+=
c
+
37
*
(
c
)
*
(
i
==
15
);
o
[
i
]
-=
c
<<
16
;
if
(
b
){
// added to have a look at what is going on in there
printf
(
"%2i : ---------------------------------------------
\n
"
,
i
);
for
(
int
j
=
0
;
j
<
16
;
++
j
)
{
printf
(
"%2i: "
,
j
);
print_bin64
(
o
[
j
]);
}
}
}
}
int
main
(
int
argc
,
char
const
*
argv
[])
{
gf
o
;
i64
val
=
0xFFFF
;
for
(
int
i
=
0
;
i
<
16
;
++
i
)
{
o
[
i
]
=
val
;
}
o
[
15
]
=
val
|
(
val
<<
32
);
for
(
int
i
=
0
;
i
<
16
;
++
i
)
{
printf
(
"%2i: "
,
i
);
print_bin64
(
o
[
i
]);
}
printf
(
"#################################################### EXP: 2 carry is not enough
\n
"
);
printf
(
"carry 1
\n
"
);
car25519
(
o
,
0
);
printf
(
"result carry 1:__________________________________________
\n
"
);
print_o
(
o
);
printf
(
"carry 2
\n
"
);
car25519
(
o
,
0
);
printf
(
"result carry 2:__________________________________________
\n
"
);
print_o
(
o
);
printf
(
"#################################################### EXP: -15, 1 step
\n
"
);
for
(
int
i
=
0
;
i
<
16
;
++
i
)
{
o
[
i
]
=
0
;
}
o
[
0
]
=
-
15
;
print_o
(
o
);
print_bin64
(
o
[
0
]);
o
[
0
]
+=
(
1LL
<<
16
);
i64
c
;
printf
(
"o[0]+=(1LL<<16)
\n
"
);
print_bin64
(
o
[
0
]);
c
=
o
[
0
]
>>
16
;
printf
(
"c=o[0]>>16;
\n
"
);
print_bin64
(
c
);
o
[
1
]
+=
c
-
1
;
printf
(
"o[1]+=c-1;
\n
"
);
print_bin64
(
o
[
1
]);
o
[
0
]
-=
c
<<
16
;
printf
(
"o[0]-=c<<16;
\n
"
);
print_bin64
(
o
[
0
]);
printf
(
"result carry step 1:_____________________________________
\n
"
);
print_o
(
o
);
printf
(
"#################################################### EXP: -15 all steps
\n
"
);
for
(
int
i
=
0
;
i
<
16
;
++
i
)
{
o
[
i
]
=
0
;
}
o
[
15
]
=
-
1
;
print_o
(
o
);
car25519
(
o
,
0
);
printf
(
"result carry 1:__________________________________________
\n
"
);
print_o
(
o
);
car25519
(
o
,
0
);
printf
(
"result carry 2:__________________________________________
\n
"
);
print_o
(
o
);
car25519
(
o
,
0
);
printf
(
"result carry 3:__________________________________________
\n
"
);
print_o
(
o
);
printf
(
"####################################################
\n
"
);
i64
t
=
-
0xFFFFF
;
printf
(
"%li
\n
"
,
t
);
print_bin64
(
t
);
t
-=
(
t
>>
16
)
<<
16
;
printf
(
"%li
\n
"
,
t
);
print_bin64
(
t
);
printf
(
"####################################################
\n
"
);
t
=
-
0xFFFC5
;
printf
(
"%li
\n
"
,
t
);
print_bin64
(
t
);
i64
tt
=
t
>>
16
;
printf
(
"%li
\n
"
,
tt
);
print_bin64
(
tt
);
tt
<<=
16
;
printf
(
"%li
\n
"
,
tt
);
print_bin64
(
tt
);
t
-=
tt
;
printf
(
"%li
\n
"
,
t
);
print_bin64
(
t
);
return
0
;
}
proofs/spec/C/tweetnacl.c
deleted
100755 → 0
View file @
f5059abf
#include "tweetnacl.h"
#define FOR(i,n) for (i = 0;i < n;++i)
#define sv static void
typedef
unsigned
char
u8
;
typedef
unsigned
long
u32
;
typedef
unsigned
long
long
u64
;
typedef
long
long
i64
;
typedef
i64
gf
[
16
];
extern
void
randombytes
(
u8
*
,
u64
);
static
const
u8
_0
[
16
],
_9
[
32
]
=
{
9
};
static
const
gf
gf0
,
gf1
=
{
1
},
_121665
=
{
0xDB41
,
1
},
D
=
{
0x78a3
,
0x1359
,
0x4dca
,
0x75eb
,
0xd8ab
,
0x4141
,
0x0a4d
,
0x0070
,
0xe898
,
0x7779
,
0x4079
,
0x8cc7
,
0xfe73
,
0x2b6f
,
0x6cee
,
0x5203
},
D2
=
{
0xf159
,
0x26b2
,
0x9b94
,
0xebd6
,
0xb156
,
0x8283
,
0x149a
,
0x00e0
,
0xd130
,
0xeef3
,
0x80f2
,
0x198e
,
0xfce7
,
0x56df
,
0xd9dc
,
0x2406
},
X
=
{
0xd51a
,
0x8f25
,
0x2d60
,
0xc956
,
0xa7b2
,
0x9525
,
0xc760
,
0x692c
,
0xdc5c
,
0xfdd6
,
0xe231
,
0xc0a4
,
0x53fe
,
0xcd6e
,
0x36d3
,
0x2169
},
Y
=
{
0x6658
,
0x6666
,
0x6666
,
0x6666
,
0x6666
,
0x6666
,
0x6666
,
0x6666
,
0x6666
,
0x6666
,
0x6666
,
0x6666
,
0x6666
,
0x6666
,
0x6666
,
0x6666
},
I
=
{
0xa0b0
,
0x4a0e
,
0x1b27
,
0xc4ee
,
0xe478
,
0xad2f
,
0x1806
,
0x2f43
,
0xd7a7
,
0x3dfb
,
0x0099
,
0x2b4d
,
0xdf0b
,
0x4fc1
,
0x2480
,
0x2b83
};
static
u32
L32
(
u32
x
,
int
c
)
{
return
(
x
<<
c
)
|
((
x
&
0xffffffff
)
>>
(
32
-
c
));
}
static
u32
ld32
(
const
u8
*
x
)
{
u32
u
=
x
[
3
];
u
=
(
u
<<
8
)
|
x
[
2
];
u
=
(
u
<<
8
)
|
x
[
1
];
return
(
u
<<
8
)
|
x
[
0
];
}
static
u64
dl64
(
const
u8
*
x
)
{
u64
i
,
u
=
0
;
FOR
(
i
,
8
)
u
=
(
u
<<
8
)
|
x
[
i
];
return
u
;
}
sv
st32
(
u8
*
x
,
u32
u
)
{
int
i
;
FOR
(
i
,
4
)
{
x
[
i
]
=
u
;
u
>>=
8
;
}
}
sv
ts64
(
u8
*
x
,
u64
u
)
{
int
i
;
for
(
i
=
7
;
i
>=
0
;
--
i
)
{
x
[
i
]
=
u
;
u
>>=
8
;
}
}
static
int
vn
(
const
u8
*
x
,
const
u8
*
y
,
int
n
)
{
u32
i
,
d
=
0
;
FOR
(
i
,
n
)
d
|=
x
[
i
]
^
y
[
i
];
return
(
1
&
((
d
-
1
)
>>
8
))
-
1
;
}
int
crypto_verify_16
(
const
u8
*
x
,
const
u8
*
y
)
{
return
vn
(
x
,
y
,
16
);
}
int
crypto_verify_32
(
const
u8
*
x
,
const
u8
*
y
)
{
return
vn
(
x
,
y
,
32
);
}
sv
core
(
u8
*
out
,
const
u8
*
in
,
const
u8
*
k
,
const
u8
*
c
,
int
h
)
{
u32
w
[
16
],
x
[
16
],
y
[
16
],
t
[
4
];
int
i
,
j
,
m
;
FOR
(
i
,
4
)
{
x
[
5
*
i
]
=
ld32
(
c
+
4
*
i
);
x
[
1
+
i
]
=
ld32
(
k
+
4
*
i
);
x
[
6
+
i
]
=
ld32
(
in
+
4
*
i
);
x
[
11
+
i
]
=
ld32
(
k
+
16
+
4
*
i
);
}
FOR
(
i
,
16
)
y
[
i
]
=
x
[
i
];
FOR
(
i
,
20
)
{
FOR
(
j
,
4
)
{
FOR
(
m
,
4
)
t
[
m
]
=
x
[(
5
*
j
+
4
*
m
)
%
16
];
t
[
1
]
^=
L32
(
t
[
0
]
+
t
[
3
],
7
);
t
[
2
]
^=
L32
(
t
[
1
]
+
t
[
0
],
9
);
t
[
3
]
^=
L32
(
t
[
2
]
+
t
[
1
],
13
);
t
[
0
]
^=
L32
(
t
[
3
]
+
t
[
2
],
18
);
FOR
(
m
,
4
)
w
[
4
*
j
+
(
j
+
m
)
%
4
]
=
t
[
m
];
}
FOR
(
m
,
16
)
x
[
m
]
=
w
[
m
];
}
if
(
h
)
{
FOR
(
i
,
16
)
x
[
i
]
+=
y
[
i
];
FOR
(
i
,
4
)
{
x
[
5
*
i
]
-=
ld32
(
c
+
4
*
i
);
x
[
6
+
i
]
-=
ld32
(
in
+
4
*
i
);
}
FOR
(
i
,
4
)
{
st32
(
out
+
4
*
i
,
x
[
5
*
i
]);
st32
(
out
+
16
+
4
*
i
,
x
[
6
+
i
]);
}
}
else
FOR
(
i
,
16
)
st32
(
out
+
4
*
i
,
x
[
i
]
+
y
[
i
]);
}
int
crypto_core_salsa20
(
u8
*
out
,
const
u8
*
in
,
const
u8
*
k
,
const
u8
*
c
)
{
core
(
out
,
in
,
k
,
c
,
0
);
return
0
;
}
int
crypto_core_hsalsa20
(
u8
*
out
,
const
u8
*
in
,
const
u8
*
k
,
const
u8
*
c
)
{
core
(
out
,
in
,
k
,
c
,
1
);
return
0
;
}
static
const
u8
sigma
[
16
]
=
"expand 32-byte k"
;
int
crypto_stream_salsa20_xor
(
u8
*
c
,
const
u8
*
m
,
u64
b
,
const
u8
*
n
,
const
u8
*
k
)
{
u8
z
[
16
],
x
[
64
];
u32
u
,
i
;
if
(
!
b
)
return
0
;
FOR
(
i
,
16
)
z
[
i
]
=
0
;
FOR
(
i
,
8
)
z
[
i
]
=
n
[
i
];
while
(
b
>=
64
)
{
crypto_core_salsa20
(
x
,
z
,
k
,
sigma
);
FOR
(
i
,
64
)
c
[
i
]
=
(
m
?
m
[
i
]
:
0
)
^
x
[
i
];
u
=
1
;
for
(
i
=
8
;
i
<
16
;
++
i
)
{
u
+=
(
u32
)
z
[
i
];
z
[
i
]
=
u
;
u
>>=
8
;
}
b
-=
64
;
c
+=
64
;
if
(
m
)
m
+=
64
;
}
if
(
b
)
{
crypto_core_salsa20
(
x
,
z
,
k
,
sigma
);
FOR
(
i
,
b
)
c
[
i
]
=
(
m
?
m
[
i
]
:
0
)
^
x
[
i
];
}
return
0
;
}
int
crypto_stream_salsa20
(
u8
*
c
,
u64
d
,
const
u8
*
n
,
const
u8
*
k
)
{
return
crypto_stream_salsa20_xor
(
c
,
0
,
d
,
n
,
k
);
}
int
crypto_stream
(
u8
*
c
,
u64
d
,
const
u8
*
n
,
const
u8
*
k
)
{
u8
s
[
32
];
crypto_core_hsalsa20
(
s
,
n
,
k
,
sigma
);
return
crypto_stream_salsa20
(
c
,
d
,
n
+
16
,
s
);
}
int
crypto_stream_xor
(
u8
*
c
,
const
u8
*
m
,
u64
d
,
const
u8
*
n
,
const
u8
*
k
)
{
u8
s
[
32
];
crypto_core_hsalsa20
(
s
,
n
,
k
,
sigma
);
return
crypto_stream_salsa20_xor
(
c
,
m
,
d
,
n
+
16
,
s
);
}
sv
add1305
(
u32
*
h
,
const
u32
*
c
)
{
u32
j
,
u
=
0
;
FOR
(
j
,
17
)
{
u
+=
h
[
j
]
+
c
[
j
];
h
[
j
]
=
u
&
255
;
u
>>=
8
;
}
}
static
const
u32
minusp
[
17
]
=
{
5
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
252
}
;
int
crypto_onetimeauth
(
u8
*
out
,
const
u8
*
m
,
u64
n
,
const
u8
*
k
)
{
u32
s
,
i
,
j
,
u
,
x
[
17
],
r
[
17
],
h
[
17
],
c
[
17
],
g
[
17
];
FOR
(
j
,
17
)
r
[
j
]
=
h
[
j
]
=
0
;
FOR
(
j
,
16
)
r
[
j
]
=
k
[
j
];
r
[
3
]
&=
15
;
r
[
4
]
&=
252
;
r
[
7
]
&=
15
;
r
[
8
]
&=
252
;
r
[
11
]
&=
15
;
r
[
12
]
&=
252
;
r
[
15
]
&=
15
;
while
(
n
>
0
)
{
FOR
(
j
,
17
)
c
[
j
]
=
0
;
for
(
j
=
0
;(
j
<
16
)
&&
(
j
<
n
);
++
j
)
c
[
j
]
=
m
[
j
];
c
[
j
]
=
1
;
m
+=
j
;
n
-=
j
;