aboutsummaryrefslogtreecommitdiff
path: root/core/crypto/_weierstrass/tools/ecc_gen_tables.odin
blob: 609c19cd0e1769cba6c74200c6ede66d7eec3b61 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package weistrass_tools

import secec "core:crypto/_weierstrass"
import "core:fmt"
import path "core:path/filepath"
import "core:os"
import "core:strings"

// Yes this leaks memory, fite me IRL.

GENERATED :: `/*
	------ GENERATED ------ DO NOT EDIT ------ GENERATED ------ DO NOT EDIT ------ GENERATED ------
*/`

main :: proc() {
	gen_tables("p256r1")
	gen_tables("p384r1")
}

gen_tables :: proc($CURVE: string) {
	when CURVE == "p256r1" {
		Affine_Point_p256r1 :: struct {
			x: secec.Field_Element_p256r1,
			y: secec.Field_Element_p256r1,
		}

		Multiply_Table_hi: [32][15]Affine_Point_p256r1
		Multiply_Table_lo: [32][15]Affine_Point_p256r1

		SC_LEN :: 32

		g, p: secec.Point_p256r1
	} else when CURVE == "p384r1" {
		Affine_Point_p384r1 :: struct {
			x: secec.Field_Element_p384r1,
			y: secec.Field_Element_p384r1,
		}
		Multiply_Table_hi: [48][15]Affine_Point_p384r1
		Multiply_Table_lo: [48][15]Affine_Point_p384r1

		SC_LEN :: 48

		g, p: secec.Point_p384r1
	} else {
		#panic("weistrass/tools: invalid curve")
	}

	secec.pt_generator(&g)

	// Precompute ([1,15] << n) * G multiples of G, MSB->LSB
	for i in 0..<SC_LEN {
		b: [SC_LEN]byte
		for j in 1..<16 {
			b[i] = u8(j) << 4
			secec.pt_scalar_mul_bytes(&p, &g, b[:], true)
			secec.pt_rescale(&p, &p)
			secec.fe_set(&Multiply_Table_hi[i][j-1].x, &p.x)
			secec.fe_set(&Multiply_Table_hi[i][j-1].y, &p.y)

			b[i] = u8(j)
			secec.pt_scalar_mul_bytes(&p, &g, b[:], true)
			secec.pt_rescale(&p, &p)
			secec.fe_set(&Multiply_Table_lo[i][j-1].x, &p.x)
			secec.fe_set(&Multiply_Table_lo[i][j-1].y, &p.y)

			b[i] = 0
		}
	}

	fn_ := "sec" + CURVE + "_table.odin"
	fn := path.join({ODIN_ROOT, "core", "crypto", "_weierstrass", fn_})
	bld: strings.Builder
	w := strings.to_writer(&bld)

	fmt.wprintln(w, "package _weierstrass")
	fmt.wprintln(w, "")
	fmt.wprintln(w, GENERATED)
	fmt.wprintln(w, "")
	fmt.wprintln(w, "import \"core:crypto\"")
	fmt.wprintln(w, "")
	fmt.wprintln(w, "when crypto.COMPACT_IMPLS == false {")

	fmt.wprintln(w, "\t@(private,rodata)")
	fmt.wprintf(w, "\tGen_Multiply_Table_%s_hi := [%d][15]Affine_Point_%s {{\n", CURVE, SC_LEN, CURVE)
	for &v, i in Multiply_Table_hi {
		fmt.wprintln(w, "\t\t{")
		for &ap, j in v {
			fmt.wprintln(w, "\t\t\t{")

			x, y := &ap.x, &ap.y
			when CURVE == "p256r1" {
				fmt.wprintf(w, "\t\t\t\t{{%d, %d, %d, %d},\n", x[0], x[1], x[2], x[3])
				fmt.wprintf(w, "\t\t\t\t{{%d, %d, %d, %d},\n", y[0], y[1], y[2], y[3])
			} else when CURVE == "p384r1" {
				fmt.wprintf(w, "\t\t\t\t{{%d, %d, %d, %d, %d, %d},\n", x[0], x[1], x[2], x[3], x[4], x[5])
				fmt.wprintf(w, "\t\t\t\t{{%d, %d, %d, %d, %d, %d},\n", y[0], y[1], y[2], y[3], y[4], y[5])
			}

			fmt.wprintln(w, "\t\t\t},")
		}
		fmt.wprintln(w, "\t\t},")
	}
	fmt.wprintln(w, "\t}\n")

	fmt.wprintln(w, "\t@(private,rodata)")
	fmt.wprintf(w, "\tGen_Multiply_Table_%s_lo := [%d][15]Affine_Point_%s {{\n", CURVE, SC_LEN, CURVE)
	for &v, i in Multiply_Table_lo {
		fmt.wprintln(w, "\t\t{")
		for &ap, j in v {
			fmt.wprintln(w, "\t\t\t{")

			x, y := &ap.x, &ap.y
			when CURVE == "p256r1" {
				fmt.wprintf(w, "\t\t\t\t{{%d, %d, %d, %d},\n", x[0], x[1], x[2], x[3])
				fmt.wprintf(w, "\t\t\t\t{{%d, %d, %d, %d},\n", y[0], y[1], y[2], y[3])
			} else when CURVE == "p384r1" {
				fmt.wprintf(w, "\t\t\t\t{{%d, %d, %d, %d, %d, %d},\n", x[0], x[1], x[2], x[3], x[4], x[5])
				fmt.wprintf(w, "\t\t\t\t{{%d, %d, %d, %d, %d, %d},\n", y[0], y[1], y[2], y[3], y[4], y[5])
			}

			fmt.wprintln(w, "\t\t\t},")
		}
		fmt.wprintln(w, "\t\t},")
	}
	fmt.wprintln(w, "\t}")

	fmt.wprintln(w, "}")

	_ = os.write_entire_file(fn, transmute([]byte)(strings.to_string(bld)))
}