Mirror of BoringSSL (grpc依赖)
https://boringssl.googlesource.com/boringssl
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
222 lines
6.1 KiB
222 lines
6.1 KiB
#!/usr/bin/env python |
|
# coding=utf-8 |
|
# Copyright (c) 2020, Google Inc. |
|
# |
|
# Permission to use, copy, modify, and/or distribute this software for any |
|
# purpose with or without fee is hereby granted, provided that the above |
|
# copyright notice and this permission notice appear in all copies. |
|
# |
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY |
|
# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION |
|
# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN |
|
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|
|
|
import StringIO |
|
import subprocess |
|
|
|
# Base field Z_p |
|
p = 2**255 - 19 |
|
|
|
def modp_inv(x): |
|
return pow(x, p-2, p) |
|
|
|
# Square root of -1 |
|
modp_sqrt_m1 = pow(2, (p-1) // 4, p) |
|
|
|
# Compute corresponding x-coordinate, with low bit corresponding to |
|
# sign, or return None on failure |
|
def recover_x(y, sign): |
|
if y >= p: |
|
return None |
|
x2 = (y*y-1) * modp_inv(d*y*y+1) |
|
if x2 == 0: |
|
if sign: |
|
return None |
|
else: |
|
return 0 |
|
|
|
# Compute square root of x2 |
|
x = pow(x2, (p+3) // 8, p) |
|
if (x*x - x2) % p != 0: |
|
x = x * modp_sqrt_m1 % p |
|
if (x*x - x2) % p != 0: |
|
return None |
|
|
|
if (x & 1) != sign: |
|
x = p - x |
|
return x |
|
|
|
# Curve constant |
|
d = -121665 * modp_inv(121666) % p |
|
|
|
# Base point |
|
g_y = 4 * modp_inv(5) % p |
|
g_x = recover_x(g_y, 0) |
|
|
|
# Points are represented as affine tuples (x, y). |
|
|
|
def point_add(P, Q): |
|
x1, y1 = P |
|
x2, y2 = Q |
|
x3 = ((x1*y2 + y1*x2) * modp_inv(1 + d*x1*x2*y1*y2)) % p |
|
y3 = ((y1*y2 + x1*x2) * modp_inv(1 - d*x1*x2*y1*y2)) % p |
|
return (x3, y3) |
|
|
|
# Computes Q = s * P |
|
def point_mul(s, P): |
|
Q = (0, 1) # Neutral element |
|
while s > 0: |
|
if s & 1: |
|
Q = point_add(Q, P) |
|
P = point_add(P, P) |
|
s >>= 1 |
|
return Q |
|
|
|
def to_bytes(x): |
|
ret = bytearray(32) |
|
for i in range(len(ret)): |
|
ret[i] = x % 256 |
|
x >>= 8 |
|
assert x == 0 |
|
return ret |
|
|
|
def to_ge_precomp(P): |
|
# typedef struct { |
|
# fe_loose yplusx; |
|
# fe_loose yminusx; |
|
# fe_loose xy2d; |
|
# } ge_precomp; |
|
x, y = P |
|
return ((y + x) % p, (y - x) % p, (x * y * 2 * d) % p) |
|
|
|
def to_base_25_5(x): |
|
limbs = (26, 25, 26, 25, 26, 25, 26, 25, 26, 25) |
|
ret = [] |
|
for l in limbs: |
|
ret.append(x & ((1<<l) - 1)) |
|
x >>= l |
|
assert x == 0 |
|
return ret |
|
|
|
def to_base_51(x): |
|
ret = [] |
|
for _ in range(5): |
|
ret.append(x & ((1<<51) - 1)) |
|
x >>= 51 |
|
assert x == 0 |
|
return ret |
|
|
|
def to_literal(x): |
|
ret = "{{\n#if defined(BORINGSSL_CURVE25519_64BIT)\n" |
|
ret += ", ".join(map(str, to_base_51(x))) |
|
ret += "\n#else\n" |
|
ret += ", ".join(map(str, to_base_25_5(x))) |
|
ret += "\n#endif\n}}" |
|
return ret |
|
|
|
def main(): |
|
d2 = (2 * d) % p |
|
|
|
small_precomp = bytearray() |
|
for i in range(1, 16): |
|
s = (i&1) | ((i&2) << (64-1)) | ((i&4) << (128-2)) | ((i&8) << (192-3)) |
|
P = point_mul(s, (g_x, g_y)) |
|
small_precomp += to_bytes(P[0]) |
|
small_precomp += to_bytes(P[1]) |
|
|
|
large_precomp = [] |
|
for i in range(32): |
|
large_precomp.append([]) |
|
for j in range(8): |
|
P = point_mul((j + 1) << (i * 8), (g_x, g_y)) |
|
large_precomp[-1].append(to_ge_precomp(P)) |
|
|
|
bi_precomp = [] |
|
for i in range(8): |
|
P = point_mul(2*i + 1, (g_x, g_y)) |
|
bi_precomp.append(to_ge_precomp(P)) |
|
|
|
|
|
buf = StringIO.StringIO() |
|
buf.write("""/* Copyright (c) 2020, Google Inc. |
|
* |
|
* Permission to use, copy, modify, and/or distribute this software for any |
|
* purpose with or without fee is hereby granted, provided that the above |
|
* copyright notice and this permission notice appear in all copies. |
|
* |
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY |
|
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION |
|
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN |
|
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ |
|
|
|
// This file is generated from |
|
// ./make_curve25519_tables.py > curve25519_tables.h |
|
|
|
|
|
static const fe d = """) |
|
buf.write(to_literal(d)) |
|
buf.write("""; |
|
|
|
static const fe sqrtm1 = """) |
|
buf.write(to_literal(modp_sqrt_m1)) |
|
buf.write("""; |
|
|
|
static const fe d2 = """) |
|
buf.write(to_literal(d2)) |
|
buf.write("""; |
|
|
|
#if defined(OPENSSL_SMALL) |
|
|
|
// This block of code replaces the standard base-point table with a much smaller |
|
// one. The standard table is 30,720 bytes while this one is just 960. |
|
// |
|
// This table contains 15 pairs of group elements, (x, y), where each field |
|
// element is serialised with |fe_tobytes|. If |i| is the index of the group |
|
// element then consider i+1 as a four-bit number: (i₀, i₁, i₂, i₃) (where i₀ |
|
// is the most significant bit). The value of the group element is then: |
|
// (i₀×2^192 + i₁×2^128 + i₂×2^64 + i₃)G, where G is the generator. |
|
static const uint8_t k25519SmallPrecomp[15 * 2 * 32] = {""") |
|
for i, b in enumerate(small_precomp): |
|
buf.write("0x%02x, " % b) |
|
buf.write(""" |
|
}; |
|
|
|
#else |
|
|
|
// k25519Precomp[i][j] = (j+1)*256^i*B |
|
static const ge_precomp k25519Precomp[32][8] = { |
|
""") |
|
for child in large_precomp: |
|
buf.write("{\n") |
|
for val in child: |
|
buf.write("{\n") |
|
for term in val: |
|
buf.write(to_literal(term) + ",\n") |
|
buf.write("},\n") |
|
buf.write("},\n") |
|
buf.write("""}; |
|
|
|
#endif // OPENSSL_SMALL |
|
|
|
// Bi[i] = (2*i+1)*B |
|
static const ge_precomp Bi[8] = { |
|
""") |
|
for val in bi_precomp: |
|
buf.write("{\n") |
|
for term in val: |
|
buf.write(to_literal(term) + ",\n") |
|
buf.write("},\n") |
|
buf.write("""}; |
|
""") |
|
|
|
proc = subprocess.Popen(["clang-format"], stdin=subprocess.PIPE) |
|
proc.communicate(buf.getvalue()) |
|
|
|
if __name__ == "__main__": |
|
main()
|
|
|