1 /* $OpenBSD: sc25519.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */
4 * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,
5 * Peter Schwabe, Bo-Yin Yang.
6 * Copied from supercop-20130419/crypto_sign/ed25519/ref/sc25519.c
13 /*Arithmetic modulo the group order m = 2^252 + 27742317777372353535851937790883648493 = 7237005577332262213973186563042994240857116359379907606001950938285454250989 */
15 static const crypto_uint32 m
[32] = {0xED, 0xD3, 0xF5, 0x5C, 0x1A, 0x63, 0x12, 0x58, 0xD6, 0x9C, 0xF7, 0xA2, 0xDE, 0xF9, 0xDE, 0x14,
16 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
18 static const crypto_uint32 mu
[33] = {0x1B, 0x13, 0x2C, 0x0A, 0xA3, 0xE5, 0x9C, 0xED, 0xA7, 0x29, 0x63, 0x08, 0x5D, 0x21, 0x06, 0x21,
19 0xEB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F};
21 static crypto_uint32
lt(crypto_uint32 a
,crypto_uint32 b
) /* 16-bit inputs */
24 x
-= (unsigned int) b
; /* 0..65535: no; 4294901761..4294967295: yes */
25 x
>>= 31; /* 0: no; 1: yes */
29 /* Reduce coefficients of r before calling reduce_add_sub */
30 static void reduce_add_sub(sc25519
*r
)
42 t
[i
] = r
->v
[i
]-pb
+(b
<<8);
47 r
->v
[i
] ^= mask
& (r
->v
[i
] ^ t
[i
]);
50 /* Reduce coefficients of x before calling barrett_reduce */
51 static void barrett_reduce(sc25519
*r
, const crypto_uint32 x
[64])
53 /* See HAC, Alg. 14.42 */
56 crypto_uint32
*q3
= q2
+ 33;
63 for (i
= 0;i
< 66;++i
) q2
[i
] = 0;
64 for (i
= 0;i
< 33;++i
) r2
[i
] = 0;
68 if(i
+j
>= 31) q2
[i
+j
] += mu
[i
]*x
[j
+31];
74 for(i
=0;i
<33;i
++)r1
[i
] = x
[i
];
77 if(i
+j
< 33) r2
[i
+j
] += m
[i
]*q3
[j
];
90 r
->v
[i
] = r1
[i
]-pb
+(b
<<8);
94 /* XXX: Can it really happen that r<0?, See HAC, Alg 14.42, Step 3
95 * If so: Handle it here!
102 void sc25519_from32bytes(sc25519
*r
, const unsigned char x
[32])
106 for(i
=0;i
<32;i
++) t
[i
] = x
[i
];
107 for(i
=32;i
<64;++i
) t
[i
] = 0;
108 barrett_reduce(r
, t
);
111 void shortsc25519_from16bytes(shortsc25519
*r
, const unsigned char x
[16])
114 for(i
=0;i
<16;i
++) r
->v
[i
] = x
[i
];
117 void sc25519_from64bytes(sc25519
*r
, const unsigned char x
[64])
121 for(i
=0;i
<64;i
++) t
[i
] = x
[i
];
122 barrett_reduce(r
, t
);
125 void sc25519_from_shortsc(sc25519
*r
, const shortsc25519
*x
)
134 void sc25519_to32bytes(unsigned char r
[32], const sc25519
*x
)
137 for(i
=0;i
<32;i
++) r
[i
] = x
->v
[i
];
140 int sc25519_iszero_vartime(const sc25519
*x
)
144 if(x
->v
[i
] != 0) return 0;
148 int sc25519_isshort_vartime(const sc25519
*x
)
152 if(x
->v
[i
] != 0) return 0;
156 int sc25519_lt_vartime(const sc25519
*x
, const sc25519
*y
)
161 if(x
->v
[i
] < y
->v
[i
]) return 1;
162 if(x
->v
[i
] > y
->v
[i
]) return 0;
167 void sc25519_add(sc25519
*r
, const sc25519
*x
, const sc25519
*y
)
170 for(i
=0;i
<32;i
++) r
->v
[i
] = x
->v
[i
] + y
->v
[i
];
173 carry
= r
->v
[i
] >> 8;
180 void sc25519_sub_nored(sc25519
*r
, const sc25519
*x
, const sc25519
*y
)
187 t
= x
->v
[i
] - y
->v
[i
] - b
;
193 void sc25519_mul(sc25519
*r
, const sc25519
*x
, const sc25519
*y
)
197 for(i
=0;i
<64;i
++)t
[i
] = 0;
201 t
[i
+j
] += x
->v
[i
] * y
->v
[j
];
203 /* Reduce coefficients */
211 barrett_reduce(r
, t
);
214 void sc25519_mul_shortsc(sc25519
*r
, const sc25519
*x
, const shortsc25519
*y
)
217 sc25519_from_shortsc(&t
, y
);
218 sc25519_mul(r
, x
, &t
);
221 void sc25519_window3(signed char r
[85], const sc25519
*s
)
227 r
[8*i
+0] = s
->v
[3*i
+0] & 7;
228 r
[8*i
+1] = (s
->v
[3*i
+0] >> 3) & 7;
229 r
[8*i
+2] = (s
->v
[3*i
+0] >> 6) & 7;
230 r
[8*i
+2] ^= (s
->v
[3*i
+1] << 2) & 7;
231 r
[8*i
+3] = (s
->v
[3*i
+1] >> 1) & 7;
232 r
[8*i
+4] = (s
->v
[3*i
+1] >> 4) & 7;
233 r
[8*i
+5] = (s
->v
[3*i
+1] >> 7) & 7;
234 r
[8*i
+5] ^= (s
->v
[3*i
+2] << 1) & 7;
235 r
[8*i
+6] = (s
->v
[3*i
+2] >> 2) & 7;
236 r
[8*i
+7] = (s
->v
[3*i
+2] >> 5) & 7;
238 r
[8*i
+0] = s
->v
[3*i
+0] & 7;
239 r
[8*i
+1] = (s
->v
[3*i
+0] >> 3) & 7;
240 r
[8*i
+2] = (s
->v
[3*i
+0] >> 6) & 7;
241 r
[8*i
+2] ^= (s
->v
[3*i
+1] << 2) & 7;
242 r
[8*i
+3] = (s
->v
[3*i
+1] >> 1) & 7;
243 r
[8*i
+4] = (s
->v
[3*i
+1] >> 4) & 7;
245 /* Making it signed */
258 void sc25519_window5(signed char r
[51], const sc25519
*s
)
264 r
[8*i
+0] = s
->v
[5*i
+0] & 31;
265 r
[8*i
+1] = (s
->v
[5*i
+0] >> 5) & 31;
266 r
[8*i
+1] ^= (s
->v
[5*i
+1] << 3) & 31;
267 r
[8*i
+2] = (s
->v
[5*i
+1] >> 2) & 31;
268 r
[8*i
+3] = (s
->v
[5*i
+1] >> 7) & 31;
269 r
[8*i
+3] ^= (s
->v
[5*i
+2] << 1) & 31;
270 r
[8*i
+4] = (s
->v
[5*i
+2] >> 4) & 31;
271 r
[8*i
+4] ^= (s
->v
[5*i
+3] << 4) & 31;
272 r
[8*i
+5] = (s
->v
[5*i
+3] >> 1) & 31;
273 r
[8*i
+6] = (s
->v
[5*i
+3] >> 6) & 31;
274 r
[8*i
+6] ^= (s
->v
[5*i
+4] << 2) & 31;
275 r
[8*i
+7] = (s
->v
[5*i
+4] >> 3) & 31;
277 r
[8*i
+0] = s
->v
[5*i
+0] & 31;
278 r
[8*i
+1] = (s
->v
[5*i
+0] >> 5) & 31;
279 r
[8*i
+1] ^= (s
->v
[5*i
+1] << 3) & 31;
280 r
[8*i
+2] = (s
->v
[5*i
+1] >> 2) & 31;
282 /* Making it signed */
295 void sc25519_2interleave2(unsigned char r
[127], const sc25519
*s1
, const sc25519
*s2
)
300 r
[4*i
] = ( s1
->v
[i
] & 3) ^ (( s2
->v
[i
] & 3) << 2);
301 r
[4*i
+1] = ((s1
->v
[i
] >> 2) & 3) ^ (((s2
->v
[i
] >> 2) & 3) << 2);
302 r
[4*i
+2] = ((s1
->v
[i
] >> 4) & 3) ^ (((s2
->v
[i
] >> 4) & 3) << 2);
303 r
[4*i
+3] = ((s1
->v
[i
] >> 6) & 3) ^ (((s2
->v
[i
] >> 6) & 3) << 2);
305 r
[124] = ( s1
->v
[31] & 3) ^ (( s2
->v
[31] & 3) << 2);
306 r
[125] = ((s1
->v
[31] >> 2) & 3) ^ (((s2
->v
[31] >> 2) & 3) << 2);
307 r
[126] = ((s1
->v
[31] >> 4) & 3) ^ (((s2
->v
[31] >> 4) & 3) << 2);