FoxiGram/TMessagesProj/jni/boringssl/crypto/fipsmodule/ec/make_tables.go
instant992 8e79f2ee9c FoxiGram: Telegram client with built-in Xray VLESS proxy
Based on Nekogram. Key additions:
- Rebrand to FoxiGram (app name, APK name, applicationId com.foxigram.app)
- Embedded Xray (VLESS+Reality) proxy client via JNI libxray.so
- Bundled hidden one-tap proxies (LTE + WiFi), read-only in UI
- Auto-restore proxy on restart, rebind to active network (LTE/WiFi)
- Server credentials externalized to git-ignored XrayServers.java (+ template)
- libxray Go source included; compiled .so, keystore, google-services.json ignored
2026-06-08 16:41:07 +04:00

591 lines
17 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright 2020 The BoringSSL Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build ignore
package main
import (
"bytes"
"crypto/elliptic"
"fmt"
"io"
"math/big"
"os"
"strings"
)
func main() {
if err := writeBuiltinCurves("builtin_curves.h"); err != nil {
fmt.Fprintf(os.Stderr, "Error writing builtin_curves.h: %s\n", err)
os.Exit(1)
}
if err := writeP256NistzTable("p256-nistz-table.h"); err != nil {
fmt.Fprintf(os.Stderr, "Error writing p256-nistz-table.h: %s\n", err)
os.Exit(1)
}
if err := writeP256Table("p256_table.h"); err != nil {
fmt.Fprintf(os.Stderr, "Error writing p256_table.h: %s\n", err)
os.Exit(1)
}
}
func writeBuiltinCurves(path string) error {
f, err := os.Create(path)
if err != nil {
return err
}
defer f.Close()
w := &columnWriter{w: f}
const fileHeader = `// Copyright 2023 The BoringSSL Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// This file is generated by make_tables.go.
`
if _, err := io.WriteString(w, fileHeader); err != nil {
return err
}
// P-224 is the only curve where we have a non-Montgomery implementation.
if err := writeCurveData(w, elliptic.P224(), true); err != nil {
return err
}
if err := writeCurveData(w, elliptic.P256(), false); err != nil {
return err
}
if err := writeCurveData(w, elliptic.P384(), false); err != nil {
return err
}
if err := writeCurveData(w, elliptic.P521(), false); err != nil {
return err
}
return nil
}
func writeCurveData(w *columnWriter, curve elliptic.Curve, includeNonMontgomery bool) error {
params := curve.Params()
if _, err := fmt.Fprintf(w, "\n// %s\n", params.Name); err != nil {
return err
}
cName := strings.Replace(params.Name, "-", "", -1)
writeDecls := func(bits int) error {
if err := writeDecl(w, curve, bits, fmt.Sprintf("k%sField", cName), params.P); err != nil {
return err
}
if err := writeDecl(w, curve, bits, fmt.Sprintf("k%sOrder", cName), params.N); err != nil {
return err
}
if includeNonMontgomery {
if err := writeDecl(w, curve, bits, fmt.Sprintf("k%sB", cName), params.B); err != nil {
return err
}
if err := writeDecl(w, curve, bits, fmt.Sprintf("k%sGX", cName), params.Gx); err != nil {
return err
}
if err := writeDecl(w, curve, bits, fmt.Sprintf("k%sGY", cName), params.Gy); err != nil {
return err
}
}
if err := writeDecl(w, curve, bits, fmt.Sprintf("k%sFieldR", cName), montgomeryR(params.P, bits)); err != nil {
return err
}
if err := writeDecl(w, curve, bits, fmt.Sprintf("k%sFieldRR", cName), montgomeryRR(params.P, bits)); err != nil {
return err
}
if err := writeDecl(w, curve, bits, fmt.Sprintf("k%sOrderRR", cName), montgomeryRR(params.N, bits)); err != nil {
return err
}
if err := writeDecl(w, curve, bits, fmt.Sprintf("k%sMontB", cName), toMontgomery(params.B, params.P, bits)); err != nil {
return err
}
if err := writeDecl(w, curve, bits, fmt.Sprintf("k%sMontGX", cName), toMontgomery(params.Gx, params.P, bits)); err != nil {
return err
}
if err := writeDecl(w, curve, bits, fmt.Sprintf("k%sMontGY", cName), toMontgomery(params.Gy, params.P, bits)); err != nil {
return err
}
return nil
}
if _, err := fmt.Fprintf(w, "[[maybe_unused]] static const uint64_t k%sFieldN0 = 0x%016x;\n", cName, montgomeryN0(params.P)); err != nil {
return err
}
if _, err := fmt.Fprintf(w, "[[maybe_unused]] static const uint64_t k%sOrderN0 = 0x%016x;\n", cName, montgomeryN0(params.N)); err != nil {
return err
}
if _, err := io.WriteString(w, "#if defined(OPENSSL_64_BIT)\n"); err != nil {
return err
}
if err := writeDecls(64); err != nil {
return err
}
if _, err := io.WriteString(w, "#elif defined(OPENSSL_32_BIT)\n"); err != nil {
return err
}
if err := writeDecls(32); err != nil {
return err
}
if _, err := io.WriteString(w, "#else\n#error \"unknown word size\"\n#endif\n"); err != nil {
return err
}
return nil
}
func writeP256NistzTable(path string) error {
curve := elliptic.P256()
tables := make([][][2]*big.Int, 0, 37)
for shift := 0; shift < 256; shift += 7 {
row := makeMultiples(curve, 64, shift)
tables = append(tables, row)
}
f, err := os.Create(path)
if err != nil {
return err
}
defer f.Close()
w := &columnWriter{w: f}
const fileHeader = `// Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved.
// Copyright (c) 2015, Intel Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// This is the precomputed constant time access table for the code in
// p256-nistz.c, for the default generator. The table consists of 37
// subtables, each subtable contains 64 affine points. The affine points are
// encoded as eight uint64's, four for the x coordinate and four for the y.
// Both values are in little-endian order. There are 37 tables because a
// signed, 6-bit wNAF form of the scalar is used and ceil(256/(6 + 1)) = 37.
// Within each table there are 64 values because the 6-bit wNAF value can take
// 64 values, ignoring the sign bit, which is implemented by performing a
// negation of the affine point when required. We would like to align it to 2MB
// in order to increase the chances of using a large page but that appears to
// lead to invalid ELF files being produced.
// This file is generated by make_tables.go.
alignas(4096) static const PRECOMP256_ROW ecp_nistz256_precomputed[37] = `
if _, err := io.WriteString(w, fileHeader); err != nil {
return err
}
if err := writeTables(w, curve, tables, writeBNMont); err != nil {
return err
}
if _, err := io.WriteString(w, ";\n"); err != nil {
return err
}
return nil
}
func writeP256Table(path string) error {
curve := elliptic.P256()
tables := [][][2]*big.Int{
makeComb(curve, 64, 4, 0),
makeComb(curve, 64, 4, 32),
}
f, err := os.Create(path)
if err != nil {
return err
}
defer f.Close()
w := &columnWriter{w: f}
const fileHeader = `// Copyright 2020 The BoringSSL Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// This file is generated by make_tables.go.
// Base point pre computation
// --------------------------
//
// Two different sorts of precomputed tables are used in the following code.
// Each contain various points on the curve, where each point is three field
// elements (x, y, z).
//
// For the base point table, z is usually 1 (0 for the point at infinity).
// This table has 2 * 16 elements, starting with the following:
// index | bits | point
// ------+---------+------------------------------
// 0 | 0 0 0 0 | 0G
// 1 | 0 0 0 1 | 1G
// 2 | 0 0 1 0 | 2^64G
// 3 | 0 0 1 1 | (2^64 + 1)G
// 4 | 0 1 0 0 | 2^128G
// 5 | 0 1 0 1 | (2^128 + 1)G
// 6 | 0 1 1 0 | (2^128 + 2^64)G
// 7 | 0 1 1 1 | (2^128 + 2^64 + 1)G
// 8 | 1 0 0 0 | 2^192G
// 9 | 1 0 0 1 | (2^192 + 1)G
// 10 | 1 0 1 0 | (2^192 + 2^64)G
// 11 | 1 0 1 1 | (2^192 + 2^64 + 1)G
// 12 | 1 1 0 0 | (2^192 + 2^128)G
// 13 | 1 1 0 1 | (2^192 + 2^128 + 1)G
// 14 | 1 1 1 0 | (2^192 + 2^128 + 2^64)G
// 15 | 1 1 1 1 | (2^192 + 2^128 + 2^64 + 1)G
// followed by a copy of this with each element multiplied by 2^32.
//
// The reason for this is so that we can clock bits into four different
// locations when doing simple scalar multiplies against the base point,
// and then another four locations using the second 16 elements.
//
// Tables for other points have table[i] = iG for i in 0 .. 16.
// fiat_p256_g_pre_comp is the table of precomputed base points
#if defined(OPENSSL_64_BIT)
static const fiat_p256_felem fiat_p256_g_pre_comp[2][15][2] = `
if _, err := io.WriteString(w, fileHeader); err != nil {
return err
}
if err := writeTables(w, curve, tables, writeU64Mont); err != nil {
return err
}
if _, err := io.WriteString(w, ";\n#else\nstatic const fiat_p256_felem fiat_p256_g_pre_comp[2][15][2] = "); err != nil {
return err
}
if err := writeTables(w, curve, tables, writeU32Mont); err != nil {
return err
}
if _, err := io.WriteString(w, ";\n#endif\n"); err != nil {
return err
}
return nil
}
// makeMultiples returns a table of the first n multiples of 2^shift * G,
// starting from 1 * 2^shift * G.
func makeMultiples(curve elliptic.Curve, n, shift int) [][2]*big.Int {
ret := make([][2]*big.Int, n)
x, y := curve.Params().Gx, curve.Params().Gy
for j := 0; j < shift; j++ {
x, y = curve.Double(x, y)
}
ret[1-1] = [2]*big.Int{x, y}
for i := 2; i <= n; i++ {
if i&1 == 0 {
x, y := curve.Double(ret[i/2-1][0], ret[i/2-1][1])
ret[i-1] = [2]*big.Int{x, y}
} else {
x, y := curve.Add(ret[i-1-1][0], ret[i-1-1][1], ret[1-1][0], ret[1-1][1])
ret[i-1] = [2]*big.Int{x, y}
}
}
return ret
}
// makeComb returns a table of 2^size - 1 points. The i-1th entry is k*G.
// If i is represented in binary by b0*2^0 + b1*2^1 + ... bn*2^n, k is
// b0*2^(shift + 0*stride) + b1*2^(shift + 1*stride) + ... + bn*2^(shift + n*stride).
// The entry for i = 0 is omitted because it is always the point at infinity.
func makeComb(curve elliptic.Curve, stride, size, shift int) [][2]*big.Int {
ret := make([][2]*big.Int, 1<<size-1)
x, y := curve.Params().Gx, curve.Params().Gy
for j := 0; j < shift; j++ {
x, y = curve.Double(x, y)
}
ret[1<<0-1] = [2]*big.Int{x, y}
for i := 1; i < size; i++ {
// Entry 2^i is entry 2^(i-1) doubled stride times.
x, y = ret[1<<(i-1)-1][0], ret[1<<(i-1)-1][1]
for j := 0; j < stride; j++ {
x, y = curve.Double(x, y)
}
ret[1<<i-1] = [2]*big.Int{x, y}
// The remaining entries with MSB 2^i are computed by adding entry 2^i
// to the corresponding previous entry.
for j := 1; j < 1<<i; j++ {
x, y = curve.Add(ret[1<<i-1][0], ret[1<<i-1][1], ret[j-1][0], ret[j-1][1])
ret[1<<i+j-1] = [2]*big.Int{x, y}
}
}
return ret
}
func montgomeryR(p *big.Int, wordSize int) *big.Int {
// R is the bit width of p, rounded up to word size.
rounded := wordSize * ((p.BitLen() + wordSize - 1) / wordSize)
R := new(big.Int).SetInt64(1)
R.Lsh(R, uint(rounded))
R.Mod(R, p)
return R
}
func montgomeryRR(p *big.Int, wordSize int) *big.Int {
R := montgomeryR(p, wordSize)
R.Mul(R, R)
R.Mod(R, p)
return R
}
func montgomeryN0(p *big.Int) uint64 {
two64 := new(big.Int)
two64 = two64.SetBit(two64, 64, 1)
n0 := new(big.Int).Neg(p)
n0 = n0.ModInverse(n0, two64)
if !n0.IsUint64() {
panic("n0 should fit in uint64")
}
return n0.Uint64()
}
// toMontgomery returns n×R mod p, where R is the Montgomery factor.
func toMontgomery(n, p *big.Int, wordSize int) *big.Int {
ret := montgomeryR(p, wordSize)
ret.Mul(ret, n)
ret.Mod(ret, p)
return ret
}
func bigIntToU64s(curve elliptic.Curve, n *big.Int) []uint64 {
words := (curve.Params().BitSize + 63) / 64
ret := make([]uint64, words)
bytes := n.Bytes()
for i, b := range bytes {
i = len(bytes) - i - 1
ret[i/8] |= uint64(b) << (8 * (i % 8))
}
return ret
}
func bigIntToU32s(curve elliptic.Curve, n *big.Int) []uint32 {
words := (curve.Params().BitSize + 31) / 32
ret := make([]uint32, words)
bytes := n.Bytes()
for i, b := range bytes {
i = len(bytes) - i - 1
ret[i/4] |= uint32(b) << (8 * (i % 4))
}
return ret
}
// A columnWriter is an io.Writer that tracks the number of columns in the
// current line.
type columnWriter struct {
w io.Writer
column int
}
func (c *columnWriter) Write(p []byte) (n int, err error) {
n, err = c.w.Write(p)
idx := bytes.LastIndexByte(p[:n], '\n')
if idx < 0 {
c.column += n
} else {
c.column = n - idx - 1
}
return
}
func writeIndent(w io.Writer, indent int) error {
for i := 0; i < indent; i++ {
if _, err := io.WriteString(w, " "); err != nil {
return err
}
}
return nil
}
func writeWordsBraced[Word any](w *columnWriter, words []Word, format func(Word) string) error {
if _, err := io.WriteString(w, "{"); err != nil {
return err
}
if err := writeWords(w, words, format); err != nil {
return err
}
if _, err := io.WriteString(w, "}"); err != nil {
return err
}
return nil
}
func writeWords[Word any](w *columnWriter, words []Word, format func(Word) string) error {
indent := w.column
for i, word := range words {
str := format(word)
if i > 0 {
if w.column+1+len(str) > 80 {
if _, err := io.WriteString(w, ",\n"); err != nil {
return err
}
if err := writeIndent(w, indent); err != nil {
return err
}
} else {
if _, err := io.WriteString(w, ", "); err != nil {
return err
}
}
}
if _, err := io.WriteString(w, str); err != nil {
return err
}
}
return nil
}
func writeDecl(w *columnWriter, curve elliptic.Curve, bits int, decl string, n *big.Int) error {
if _, err := fmt.Fprintf(w, "[[maybe_unused]] static const uint%d_t %s[] = {\n ", bits, decl); err != nil {
return err
}
if bits == 32 {
if err := writeWords(w, bigIntToU32s(curve, n), formatU32); err != nil {
return err
}
} else if bits == 64 {
if err := writeWords(w, bigIntToU64s(curve, n), formatU64); err != nil {
return err
}
} else {
panic("unknown bit count")
}
if _, err := fmt.Fprintf(w, "};\n"); err != nil {
return err
}
return nil
}
func formatBN(word uint64) string {
return fmt.Sprintf("TOBN(0x%08x, 0x%08x)", uint32(word>>32), uint32(word))
}
func formatU64(word uint64) string {
return fmt.Sprintf("0x%016x", word)
}
func formatU32(word uint32) string {
return fmt.Sprintf("0x%08x", word)
}
func writeBNMont(w *columnWriter, curve elliptic.Curve, n *big.Int) error {
n32 := toMontgomery(n, curve.Params().P, 32)
n64 := toMontgomery(n, curve.Params().P, 64)
if n32.Cmp(n64) != 0 {
panic(fmt.Sprintf("Montgomery form for %s is inconsistent between 32-bit and 64-bit", curve.Params().Name))
}
return writeWordsBraced(w, bigIntToU64s(curve, n64), formatBN)
}
func writeU64Mont(w *columnWriter, curve elliptic.Curve, n *big.Int) error {
n = toMontgomery(n, curve.Params().P, 64)
return writeWordsBraced(w, bigIntToU64s(curve, n), formatU64)
}
func writeU32Mont(w *columnWriter, curve elliptic.Curve, n *big.Int) error {
n = toMontgomery(n, curve.Params().P, 32)
return writeWordsBraced(w, bigIntToU32s(curve, n), formatU32)
}
type writeBigIntFunc func(w *columnWriter, curve elliptic.Curve, n *big.Int) error
func writeTable(w *columnWriter, curve elliptic.Curve, table [][2]*big.Int, writeBigInt writeBigIntFunc) error {
if _, err := io.WriteString(w, "{"); err != nil {
return err
}
indent := w.column
for i, point := range table {
if i != 0 {
if _, err := io.WriteString(w, ",\n"); err != nil {
return err
}
if err := writeIndent(w, indent); err != nil {
return err
}
}
if _, err := io.WriteString(w, "{"); err != nil {
return err
}
if err := writeBigInt(w, curve, point[0]); err != nil {
return err
}
if _, err := io.WriteString(w, ",\n"); err != nil {
return err
}
if err := writeIndent(w, indent+1); err != nil {
return err
}
if err := writeBigInt(w, curve, point[1]); err != nil {
return err
}
if _, err := io.WriteString(w, "}"); err != nil {
return err
}
}
if _, err := io.WriteString(w, "}"); err != nil {
return err
}
return nil
}
func writeTables(w *columnWriter, curve elliptic.Curve, tables [][][2]*big.Int, writeBigInt writeBigIntFunc) error {
if _, err := io.WriteString(w, "{\n "); err != nil {
return err
}
indent := w.column
for i, table := range tables {
if i != 0 {
if _, err := io.WriteString(w, ",\n"); err != nil {
return err
}
if err := writeIndent(w, indent); err != nil {
return err
}
}
if err := writeTable(w, curve, table, writeBigInt); err != nil {
return err
}
}
if _, err := io.WriteString(w, "}"); err != nil {
return err
}
return nil
}