aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFaker-09 <shrybman@teksavvy.com>2026-01-29 11:35:24 -0500
committerGitHub <noreply@github.com>2026-01-29 11:35:24 -0500
commit30ef01ee8d1175dc5a974d8bee62b7ea00651941 (patch)
treecddb56cfe63f3752b8b7a8c314d9cc652f22ec28
parentf6322b4b31fb0a5cc343d4bae31ebc09639e3403 (diff)
parent70059b0fba3099d0d67232ed89c268710f435a36 (diff)
Merge branch 'odin-lang:master' into vet_flags
-rw-r--r--base/runtime/core.odin1
-rw-r--r--base/runtime/error_checks.odin20
-rw-r--r--base/runtime/print.odin398
-rw-r--r--core/container/handle_map/doc.odin56
-rw-r--r--core/container/handle_map/dynamic_handle_map.odin141
-rw-r--r--core/container/handle_map/static_handle_map.odin221
-rw-r--r--core/container/xar/xar.odin15
-rw-r--r--core/crypto/_chacha20/ref/chacha20_ref.odin289
-rw-r--r--core/crypto/_edwards25519/edwards25519.odin4
-rw-r--r--core/crypto/_edwards25519/edwards25519_scalar_mul.odin139
-rw-r--r--core/crypto/_edwards25519/edwards25519_scalar_mul_base.odin147
-rw-r--r--core/crypto/_edwards25519/edwards25519_table.odin4947
-rw-r--r--core/crypto/_edwards25519/tools/edwards_gen_tables.odin134
-rw-r--r--core/crypto/_fiat/field_p256r1/field.odin346
-rw-r--r--core/crypto/_fiat/field_p256r1/field64.odin501
-rw-r--r--core/crypto/_fiat/field_scalar25519/field.odin7
-rw-r--r--core/crypto/_fiat/field_scalarp256r1/field.odin210
-rw-r--r--core/crypto/_fiat/field_scalarp256r1/field64.odin569
-rw-r--r--core/crypto/_subtle/subtle.odin42
-rw-r--r--core/crypto/_weierstrass/fe.odin135
-rw-r--r--core/crypto/_weierstrass/point.odin548
-rw-r--r--core/crypto/_weierstrass/point_s11n_sec.odin95
-rw-r--r--core/crypto/_weierstrass/sc.odin76
-rw-r--r--core/crypto/_weierstrass/scalar_mul.odin204
-rw-r--r--core/crypto/_weierstrass/secp256r1_table.odin3985
-rw-r--r--core/crypto/_weierstrass/tools/ecc_gen_tables.odin99
-rw-r--r--core/crypto/crypto.odin16
-rw-r--r--core/crypto/ecdh/doc.odin4
-rw-r--r--core/crypto/ecdh/ecdh.odin404
-rw-r--r--core/crypto/ed25519/ed25519.odin2
-rw-r--r--core/crypto/x25519/x25519.odin49
-rw-r--r--core/odin/ast/ast.odin1
-rw-r--r--core/odin/parser/parser.odin7
-rw-r--r--core/os/os2/path_windows.odin4
-rw-r--r--core/path/filepath/path.odin75
-rw-r--r--core/path/filepath/path_windows.odin3
-rw-r--r--core/reflect/types.odin5
-rw-r--r--core/unicode/utf8/utf8.odin19
-rw-r--r--examples/all/all_js.odin1
-rw-r--r--examples/all/all_main.odin8
-rw-r--r--src/check_expr.cpp12
-rw-r--r--src/check_stmt.cpp4
-rw-r--r--src/check_type.cpp15
-rw-r--r--src/llvm_backend_stmt.cpp3
-rw-r--r--src/parser.cpp13
-rw-r--r--src/parser.hpp1
-rw-r--r--src/types.cpp36
-rw-r--r--tests/benchmark/crypto/benchmark_ecc.odin89
-rw-r--r--tests/core/crypto/test_core_crypto_ecdh.odin154
-rw-r--r--tests/core/crypto/test_core_crypto_edwards.odin130
-rw-r--r--tests/core/crypto/test_core_crypto_weierstrass.odin486
-rw-r--r--vendor/x11/xlib/xlib_keysym.odin2
-rw-r--r--vendor/x11/xlib/xlib_procs.odin2
53 files changed, 14126 insertions, 748 deletions
diff --git a/base/runtime/core.odin b/base/runtime/core.odin
index 58a0b8ad1..5a0b3766c 100644
--- a/base/runtime/core.odin
+++ b/base/runtime/core.odin
@@ -122,6 +122,7 @@ Type_Info_Struct_Flag :: enum u8 {
raw_union = 1,
all_or_none = 2,
align = 3,
+ simple = 4,
}
Type_Info_Struct :: struct {
diff --git a/base/runtime/error_checks.odin b/base/runtime/error_checks.odin
index df6cb9485..46a8f9b1d 100644
--- a/base/runtime/error_checks.odin
+++ b/base/runtime/error_checks.odin
@@ -204,10 +204,10 @@ when ODIN_NO_RTTI {
@(cold, no_instrumentation)
handle_error :: proc "odin" (file: string, line, column: i32, from, to: typeid) -> ! {
do_msg :: proc "contextless" (i: ^int, buf: []byte, file: string, line, column: i32, from, to: typeid) -> bool {
- try_copy_string(i, buf, "Invalid type assertion from ") or_return
- try_copy_typeid(i, buf, from) or_return
- try_copy_string(i, buf, " to ") or_return
- try_copy_typeid(i, buf, to) or_return
+ write_string(i, buf, "Invalid type assertion from ") or_return
+ write_typeid(i, buf, from) or_return
+ write_string(i, buf, " to ") or_return
+ write_typeid(i, buf, to) or_return
return true
}
@@ -285,13 +285,13 @@ when ODIN_NO_RTTI {
@(cold, no_instrumentation)
handle_error :: proc "odin" (file: string, line, column: i32, from, to: typeid, from_data: rawptr) -> ! {
do_msg :: proc "contextless" (i: ^int, buf: []byte, file: string, line, column: i32, from, to, actual: typeid) -> bool {
- try_copy_string(i, buf, "Invalid type assertion from ") or_return
- try_copy_typeid(i, buf, from) or_return
- try_copy_string(i, buf, " to ") or_return
- try_copy_typeid(i, buf, to) or_return
+ write_string(i, buf, "Invalid type assertion from ") or_return
+ write_typeid(i, buf, from) or_return
+ write_string(i, buf, " to ") or_return
+ write_typeid(i, buf, to) or_return
if actual != from {
- try_copy_string(i, buf, ", actual type: ") or_return
- try_copy_typeid(i, buf, actual) or_return
+ write_string(i, buf, ", actual type: ") or_return
+ write_typeid(i, buf, actual) or_return
}
return true
}
diff --git a/base/runtime/print.odin b/base/runtime/print.odin
index 4a66f9743..2cdde8152 100644
--- a/base/runtime/print.odin
+++ b/base/runtime/print.odin
@@ -280,11 +280,22 @@ print_type :: #force_no_inline proc "contextless" (ti: ^Type_Info) {
print_byte('i' if info.signed else 'u')
print_u64(u64(8*ti.size))
}
+ switch info.endianness {
+ case .Platform: // nothing
+ case .Little: print_string("le")
+ case .Big: print_string("be")
+ }
+
case Type_Info_Rune:
print_string("rune")
case Type_Info_Float:
print_byte('f')
print_u64(u64(8*ti.size))
+ switch info.endianness {
+ case .Platform: // nothing
+ case .Little: print_string("le")
+ case .Big: print_string("be")
+ }
case Type_Info_Complex:
print_string("complex")
print_u64(u64(8*ti.size))
@@ -410,6 +421,7 @@ print_type :: #force_no_inline proc "contextless" (ti: ^Type_Info) {
if .packed in info.flags { print_string("#packed ") }
if .raw_union in info.flags { print_string("#raw_union ") }
if .all_or_none in info.flags { print_string("#all_or_none ") }
+ if .simple in info.flags { print_string("#simple ") }
if .align in info.flags {
print_string("#align(")
print_u64(u64(ti.align))
@@ -494,6 +506,9 @@ print_type :: #force_no_inline proc "contextless" (ti: ^Type_Info) {
print_type(info.elem)
case Type_Info_Matrix:
+ if info.layout == .Row_Major {
+ print_string("#row_major ")
+ }
print_string("matrix[")
print_u64(u64(info.row_count))
print_string(", ")
@@ -505,7 +520,7 @@ print_type :: #force_no_inline proc "contextless" (ti: ^Type_Info) {
@(require_results)
-try_copy_string :: proc "contextless" (i: ^int, dst: []byte, src: string) -> bool {
+write_string :: proc "contextless" (i: ^int, dst: []byte, src: string) -> bool {
if i^ < len(dst) {
i^ += copy(dst[i^:], src)
return true
@@ -515,7 +530,7 @@ try_copy_string :: proc "contextless" (i: ^int, dst: []byte, src: string) -> boo
@(require_results)
-try_copy_byte :: proc "contextless" (i: ^int, dst: []byte, src: byte) -> bool {
+write_byte :: proc "contextless" (i: ^int, dst: []byte, src: byte) -> bool {
if i^ < len(dst) {
dst[i^] = src
i^ += 1
@@ -526,7 +541,7 @@ try_copy_byte :: proc "contextless" (i: ^int, dst: []byte, src: byte) -> bool {
@(require_results)
-try_copy_u64 :: proc "contextless" (j: ^int, dst: []byte, x: u64) -> bool {
+write_u64 :: proc "contextless" (j: ^int, dst: []byte, x: u64) -> bool {
if j^ < len(dst) {
b :: u64(10)
u := x
@@ -539,33 +554,56 @@ try_copy_u64 :: proc "contextless" (j: ^int, dst: []byte, x: u64) -> bool {
}
i -= 1; a[i] = _INTEGER_DIGITS_VAR[u % b]
- return try_copy_string(j, dst, string(a[i:]))
+ return write_string(j, dst, string(a[i:]))
+ }
+ return false
+}
+
+@(require_results)
+write_i64 :: proc "contextless" (j: ^int, dst: []byte, x: i64) -> bool {
+ if j^ < len(dst) {
+ b :: u64(10)
+ u := u64(abs(x))
+ neg := x < 0
+
+ a: [129]byte
+ i := len(a)
+ for u >= b {
+ i -= 1; a[i] = _INTEGER_DIGITS_VAR[u % b]
+ u /= b
+ }
+ i -= 1; a[i] = _INTEGER_DIGITS_VAR[u % b]
+ if neg {
+ i -= 1; a[i] = '-'
+ }
+
+ return write_string(j, dst, string(a[i:]))
}
return false
}
@(require_results)
-try_copy_caller_location :: #force_no_inline proc "contextless" (i: ^int, buf: []byte, loc: Source_Code_Location) -> bool {
- try_copy_string(i, buf, loc.file_path) or_return
+write_caller_location :: #force_no_inline proc "contextless" (i: ^int, buf: []byte, loc: Source_Code_Location) -> bool {
+ write_string(i, buf, loc.file_path) or_return
when ODIN_ERROR_POS_STYLE == .Default {
- try_copy_byte(i, buf, '(') or_return
- try_copy_u64(i, buf, u64(loc.line)) or_return
+ write_byte(i, buf, '(') or_return
+ write_u64 (i, buf, u64(loc.line)) or_return
if loc.column != 0 {
- try_copy_byte(i, buf, ':') or_return
- try_copy_u64(i, buf, u64(loc.column)) or_return
+ write_byte(i, buf, ':') or_return
+ write_u64 (i, buf, u64(loc.column)) or_return
}
- try_copy_byte(i, buf, ')') or_return
+ write_byte(i, buf, ')') or_return
return true
} else when ODIN_ERROR_POS_STYLE == .Unix {
- try_copy_byte(i, buf, ':') or_return
- try_copy_u64(i, buf, u64(loc.line)) or_return
+ write_byte(i, buf, ':') or_return
+ write_u64 (i, buf, u64(loc.line)) or_return
if loc.column != 0 {
- try_copy_try_copy_bytetring(i, buf, ':') or_return
- try_copy_u64(i, buf, u64(loc.column)) or_return
+ write_byte(i, buf, ':') or_return
+ write_u64 (i, buf, u64(loc.column)) or_return
}
- try_copy_byte(i, buf, ':') or_return
+ write_byte(i, buf, ':') or_return
return true
} else {
#panic("unhandled ODIN_ERROR_POS_STYLE")
@@ -573,263 +611,325 @@ try_copy_caller_location :: #force_no_inline proc "contextless" (i: ^int, buf: [
}
@(require_results)
-try_copy_typeid :: #force_no_inline proc "contextless" (i: ^int, buf: []byte, id: typeid) -> bool {
+write_typeid :: #force_no_inline proc "contextless" (i: ^int, buf: []byte, id: typeid) -> bool {
when ODIN_NO_RTTI {
if id == nil {
- try_copy_string(i, buf, "nil") or_return
+ write_string(i, buf, "nil") or_return
} else {
- try_copy_string(i, buf, "<unknown type>") or_return
+ write_string(i, buf, "<unknown type>") or_return
}
} else {
if id == nil {
- try_copy_string(i, buf, "nil") or_return
+ write_string(i, buf, "nil") or_return
} else {
ti := type_info_of(id)
- try_copy_write_type(i, buf, ti) or_return
+ write_write_type(i, buf, ti) or_return
}
}
return true
}
+
+@(require_results)
+write_rune :: #force_no_inline proc "contextless" (i: ^int, buf: []byte, r: rune) -> (written: int, ok: bool) #no_bounds_check {
+ RUNE_SELF :: 0x80
+
+ if r < RUNE_SELF {
+ write_byte(i, buf,byte(r)) or_return
+ return 1, true
+ }
+
+ b, n := encode_rune(r)
+ prev := i^
+ write_string(i, buf, string(b[:n])) or_return
+ return i^ - prev, true
+}
+
+@(require_results)
+write_encoded_rune :: #force_no_inline proc "contextless" (i: ^int, buf: []byte, r: rune) -> bool {
+ write_byte(i, buf, '\'') or_return
+
+ switch r {
+ case '\a': write_string(i, buf, "\\a") or_return
+ case '\b': write_string(i, buf, "\\b") or_return
+ case '\e': write_string(i, buf, "\\e") or_return
+ case '\f': write_string(i, buf, "\\f") or_return
+ case '\n': write_string(i, buf, "\\n") or_return
+ case '\r': write_string(i, buf, "\\r") or_return
+ case '\t': write_string(i, buf, "\\t") or_return
+ case '\v': write_string(i, buf, "\\v") or_return
+ case:
+ if r <= 0 {
+ write_string(i, buf, "\\x00") or_return
+ } else if r < 32 {
+ n0, n1 := u8(r) >> 4, u8(r) & 0xf
+ write_string(i, buf, "\\x") or_return
+ write_byte (i, buf, _INTEGER_DIGITS_VAR[n0]) or_return
+ write_byte (i, buf, _INTEGER_DIGITS_VAR[n1]) or_return
+ } else {
+ _ = write_rune(i, buf, r) or_return
+ }
+ }
+
+ write_byte(i, buf, '\'') or_return
+ return true
+}
+
@(optimization_mode="favor_size")
-try_copy_write_type :: #force_no_inline proc "contextless" (i: ^int, buf: []byte, ti: ^Type_Info) -> bool {
+write_write_type :: #force_no_inline proc "contextless" (i: ^int, buf: []byte, ti: ^Type_Info) -> bool {
if ti == nil {
- try_copy_string(i, buf, "nil") or_return
+ write_string(i, buf, "nil") or_return
return true
}
switch info in ti.variant {
case Type_Info_Named:
- try_copy_string(i, buf, info.name) or_return
+ write_string(i, buf, info.name) or_return
case Type_Info_Integer:
switch ti.id {
- case int: try_copy_string(i, buf, "int") or_return
- case uint: try_copy_string(i, buf, "uint") or_return
- case uintptr: try_copy_string(i, buf, "uintptr") or_return
+ case int: write_string(i, buf, "int") or_return
+ case uint: write_string(i, buf, "uint") or_return
+ case uintptr: write_string(i, buf, "uintptr") or_return
case:
- try_copy_byte(i, buf, 'i' if info.signed else 'u') or_return
- try_copy_u64(i, buf, u64(8*ti.size)) or_return
+ write_byte(i, buf, 'i' if info.signed else 'u') or_return
+ write_u64 (i, buf, u64(8*ti.size)) or_return
+ }
+ switch info.endianness {
+ case .Platform: // nothing
+ case .Little: write_string(i, buf, "le") or_return
+ case .Big: write_string(i, buf, "be") or_return
}
+
case Type_Info_Rune:
- try_copy_string(i, buf, "rune") or_return
+ write_string(i, buf, "rune") or_return
case Type_Info_Float:
- try_copy_byte(i, buf, 'f') or_return
- try_copy_u64(i, buf, u64(8*ti.size)) or_return
+ write_byte(i, buf, 'f') or_return
+ write_u64(i, buf, u64(8*ti.size)) or_return
+ switch info.endianness {
+ case .Platform: // nothing
+ case .Little: write_string(i, buf, "le") or_return
+ case .Big: write_string(i, buf, "be") or_return
+ }
+
case Type_Info_Complex:
- try_copy_string(i, buf, "complex") or_return
- try_copy_u64(i, buf, u64(8*ti.size)) or_return
+ write_string(i, buf, "complex") or_return
+ write_u64 (i, buf, u64(8*ti.size)) or_return
case Type_Info_Quaternion:
- try_copy_string(i, buf, "quaternion") or_return
- try_copy_u64(i, buf, u64(8*ti.size)) or_return
+ write_string(i, buf, "quaternion") or_return
+ write_u64 (i, buf, u64(8*ti.size)) or_return
case Type_Info_String:
if info.is_cstring {
- try_copy_byte(i, buf, 'c') or_return
+ write_byte(i, buf, 'c') or_return
}
- try_copy_string(i, buf, "string") or_return
+ write_string(i, buf, "string") or_return
switch info.encoding {
case .UTF_8: /**/
- case .UTF_16: try_copy_string(i, buf, "16") or_return
+ case .UTF_16: write_string(i, buf, "16") or_return
}
case Type_Info_Boolean:
switch ti.id {
- case bool: try_copy_string(i, buf, "bool") or_return
+ case bool: write_string(i, buf, "bool") or_return
case:
- try_copy_byte(i, buf, 'b') or_return
- try_copy_u64(i, buf, u64(8*ti.size)) or_return
+ write_byte(i, buf, 'b') or_return
+ write_u64 (i, buf, u64(8*ti.size)) or_return
}
case Type_Info_Any:
- try_copy_string(i, buf, "any") or_return
+ write_string(i, buf, "any") or_return
case Type_Info_Type_Id:
- try_copy_string(i, buf, "typeid") or_return
+ write_string(i, buf, "typeid") or_return
case Type_Info_Pointer:
if info.elem == nil {
- try_copy_string(i, buf, "rawptr") or_return
+ write_string(i, buf, "rawptr") or_return
} else {
- try_copy_string(i, buf, "^") or_return
- try_copy_write_type(i, buf, info.elem) or_return
+ write_string (i, buf, "^") or_return
+ write_write_type(i, buf, info.elem) or_return
}
case Type_Info_Multi_Pointer:
- try_copy_string(i, buf, "[^]") or_return
- try_copy_write_type(i, buf, info.elem) or_return
+ write_string (i, buf, "[^]") or_return
+ write_write_type(i, buf, info.elem) or_return
case Type_Info_Soa_Pointer:
- try_copy_string(i, buf, "#soa ^") or_return
- try_copy_write_type(i, buf, info.elem) or_return
+ write_string (i, buf, "#soa ^") or_return
+ write_write_type(i, buf, info.elem) or_return
case Type_Info_Procedure:
- try_copy_string(i, buf, "proc") or_return
+ write_string(i, buf, "proc") or_return
if info.params == nil {
- try_copy_string(i, buf, "()") or_return
+ write_string(i, buf, "()") or_return
} else {
t := info.params.variant.(Type_Info_Parameters)
- try_copy_byte(i, buf, '(') or_return
+ write_byte(i, buf, '(') or_return
for t, j in t.types {
- if j > 0 { try_copy_string(i, buf, ", ") or_return }
- try_copy_write_type(i, buf, t) or_return
+ if j > 0 { write_string(i, buf, ", ") or_return }
+ write_write_type(i, buf, t) or_return
}
- try_copy_string(i, buf, ")") or_return
+ write_string(i, buf, ")") or_return
}
if info.results != nil {
- try_copy_string(i, buf, " -> ") or_return
- try_copy_write_type(i, buf, info.results) or_return
+ write_string (i, buf, " -> ") or_return
+ write_write_type(i, buf, info.results) or_return
}
case Type_Info_Parameters:
count := len(info.names)
- if count != 1 { try_copy_byte(i, buf, '(') or_return }
+ if count != 1 { write_byte(i, buf, '(') or_return }
for name, j in info.names {
- if j > 0 { try_copy_string(i, buf, ", ") or_return }
+ if j > 0 { write_string(i, buf, ", ") or_return }
t := info.types[j]
if len(name) > 0 {
- try_copy_string(i, buf, name) or_return
- try_copy_string(i, buf, ": ") or_return
+ write_string(i, buf, name) or_return
+ write_string(i, buf, ": ") or_return
}
- try_copy_write_type(i, buf, t) or_return
+ write_write_type(i, buf, t) or_return
}
- if count != 1 { try_copy_string(i, buf, ")") or_return }
+ if count != 1 { write_string(i, buf, ")") or_return }
case Type_Info_Array:
- try_copy_byte(i, buf, '[') or_return
- try_copy_u64(i, buf, u64(info.count)) or_return
- try_copy_byte(i, buf, ']') or_return
- try_copy_write_type(i, buf, info.elem) or_return
+ write_byte (i, buf, '[') or_return
+ write_u64 (i, buf, u64(info.count)) or_return
+ write_byte (i, buf, ']') or_return
+ write_write_type(i, buf, info.elem) or_return
case Type_Info_Enumerated_Array:
if info.is_sparse {
- try_copy_string(i, buf, "#sparse") or_return
+ write_string(i, buf, "#sparse") or_return
}
- try_copy_byte(i, buf, '[') or_return
- try_copy_write_type(i, buf, info.index) or_return
- try_copy_byte(i, buf, ']') or_return
- try_copy_write_type(i, buf, info.elem) or_return
+ write_byte (i, buf, '[') or_return
+ write_write_type(i, buf, info.index) or_return
+ write_byte (i, buf, ']') or_return
+ write_write_type(i, buf, info.elem) or_return
case Type_Info_Dynamic_Array:
- try_copy_string(i, buf, "[dynamic]") or_return
- try_copy_write_type(i, buf, info.elem) or_return
+ write_string (i, buf, "[dynamic]") or_return
+ write_write_type(i, buf, info.elem) or_return
case Type_Info_Slice:
- try_copy_string(i, buf, "[]") or_return
- try_copy_write_type(i, buf, info.elem) or_return
+ write_string (i, buf, "[]") or_return
+ write_write_type(i, buf, info.elem) or_return
case Type_Info_Map:
- try_copy_string(i, buf, "map[") or_return
- try_copy_write_type(i, buf, info.key) or_return
- try_copy_byte(i, buf, ']') or_return
- try_copy_write_type(i, buf, info.value) or_return
+ write_string (i, buf, "map[") or_return
+ write_write_type(i, buf, info.key) or_return
+ write_byte (i, buf, ']') or_return
+ write_write_type(i, buf, info.value) or_return
case Type_Info_Struct:
switch info.soa_kind {
case .None: // Ignore
case .Fixed:
- try_copy_string(i, buf, "#soa[") or_return
- try_copy_u64(i, buf, u64(info.soa_len)) or_return
- try_copy_byte(i, buf, ']') or_return
- try_copy_write_type(i, buf, info.soa_base_type) or_return
+ write_string (i, buf, "#soa[") or_return
+ write_u64 (i, buf, u64(info.soa_len)) or_return
+ write_byte (i, buf, ']') or_return
+ write_write_type(i, buf, info.soa_base_type) or_return
return true
case .Slice:
- try_copy_string(i, buf, "#soa[]") or_return
- try_copy_write_type(i, buf, info.soa_base_type) or_return
+ write_string (i, buf, "#soa[]") or_return
+ write_write_type(i, buf, info.soa_base_type) or_return
return true
case .Dynamic:
- try_copy_string(i, buf, "#soa[dynamic]") or_return
- try_copy_write_type(i, buf, info.soa_base_type) or_return
+ write_string (i, buf, "#soa[dynamic]") or_return
+ write_write_type(i, buf, info.soa_base_type) or_return
return true
}
- try_copy_string(i, buf, "struct ") or_return
- if .packed in info.flags { try_copy_string(i, buf, "#packed ") or_return }
- if .raw_union in info.flags { try_copy_string(i, buf, "#raw_union ") or_return }
- if .all_or_none in info.flags { try_copy_string(i, buf, "#all_or_none ") or_return }
+ write_string(i, buf, "struct ") or_return
+ if .packed in info.flags { write_string(i, buf, "#packed ") or_return }
+ if .raw_union in info.flags { write_string(i, buf, "#raw_union ") or_return }
+ if .all_or_none in info.flags { write_string(i, buf, "#all_or_none ") or_return }
+ if .simple in info.flags { write_string(i, buf, "#simple ") or_return }
if .align in info.flags {
- try_copy_string(i, buf, "#align(") or_return
- try_copy_u64(i, buf, u64(ti.align)) or_return
- try_copy_string(i, buf, ") ") or_return
+ write_string(i, buf, "#align(") or_return
+ write_u64(i, buf, u64(ti.align)) or_return
+ write_string(i, buf, ") ") or_return
}
- try_copy_byte(i, buf, '{') or_return
+ write_byte(i, buf, '{') or_return
for name, j in info.names[:info.field_count] {
- if j > 0 { try_copy_string(i, buf, ", ") or_return }
- try_copy_string(i, buf, name) or_return
- try_copy_string(i, buf, ": ") or_return
- try_copy_write_type(i, buf, info.types[j]) or_return
+ if j > 0 { write_string(i, buf, ", ") or_return }
+ write_string (i, buf, name) or_return
+ write_string (i, buf, ": ") or_return
+ write_write_type(i, buf, info.types[j]) or_return
}
- try_copy_byte(i, buf, '}') or_return
+ write_byte(i, buf, '}') or_return
case Type_Info_Union:
- try_copy_string(i, buf, "union ") or_return
+ write_string(i, buf, "union ") or_return
if info.custom_align {
- try_copy_string(i, buf, "#align(") or_return
- try_copy_u64(i, buf, u64(ti.align)) or_return
- try_copy_string(i, buf, ") ") or_return
+ write_string(i, buf, "#align(") or_return
+ write_u64 (i, buf, u64(ti.align)) or_return
+ write_string(i, buf, ") ") or_return
}
if info.no_nil {
- try_copy_string(i, buf, "#no_nil ") or_return
+ write_string(i, buf, "#no_nil ") or_return
}
- try_copy_byte(i, buf, '{') or_return
+ write_byte(i, buf, '{') or_return
for variant, j in info.variants {
- if j > 0 { try_copy_string(i, buf, ", ") or_return }
- try_copy_write_type(i, buf, variant) or_return
+ if j > 0 { write_string(i, buf, ", ") or_return }
+ write_write_type(i, buf, variant) or_return
}
- try_copy_string(i, buf, "}") or_return
+ write_string(i, buf, "}") or_return
case Type_Info_Enum:
- try_copy_string(i, buf, "enum ") or_return
- try_copy_write_type(i, buf, info.base) or_return
- try_copy_string(i, buf, " {") or_return
+ write_string (i, buf, "enum ") or_return
+ write_write_type(i, buf, info.base) or_return
+ write_string (i, buf, " {") or_return
for name, j in info.names {
- if j > 0 { try_copy_string(i, buf, ", ") or_return }
- try_copy_string(i, buf, name) or_return
+ if j > 0 { write_string(i, buf, ", ") or_return }
+ write_string(i, buf, name) or_return
}
- try_copy_string(i, buf, "}") or_return
+ write_string(i, buf, "}") or_return
case Type_Info_Bit_Set:
- try_copy_string(i, buf, "bit_set[") or_return
+ write_string(i, buf, "bit_set[") or_return
#partial switch elem in type_info_base(info.elem).variant {
case Type_Info_Enum:
- try_copy_write_type(i, buf, info.elem) or_return
+ write_write_type(i, buf, info.elem) or_return
case Type_Info_Rune:
- print_encoded_rune(rune(info.lower))
- try_copy_string(i, buf, "..") or_return
- print_encoded_rune(rune(info.upper))
+ write_encoded_rune(i, buf, rune(info.lower)) or_return
+ write_string (i, buf, "..") or_return
+ write_encoded_rune(i, buf, rune(info.upper)) or_return
case:
- print_i64(info.lower)
- try_copy_string(i, buf, "..") or_return
- print_i64(info.upper)
+ write_i64 (i, buf, info.lower) or_return
+ write_string(i, buf, "..") or_return
+ write_i64 (i, buf, info.upper) or_return
}
if info.underlying != nil {
- try_copy_string(i, buf, "; ") or_return
- try_copy_write_type(i, buf, info.underlying) or_return
+ write_string (i, buf, "; ") or_return
+ write_write_type(i, buf, info.underlying) or_return
}
- try_copy_byte(i, buf, ']') or_return
+ write_byte(i, buf, ']') or_return
case Type_Info_Bit_Field:
- try_copy_string(i, buf, "bit_field ") or_return
- try_copy_write_type(i, buf, info.backing_type) or_return
- try_copy_string(i, buf, " {") or_return
+ write_string (i, buf, "bit_field ") or_return
+ write_write_type(i, buf, info.backing_type) or_return
+ write_string (i, buf, " {") or_return
for name, j in info.names[:info.field_count] {
- if j > 0 { try_copy_string(i, buf, ", ") or_return }
- try_copy_string(i, buf, name) or_return
- try_copy_string(i, buf, ": ") or_return
- try_copy_write_type(i, buf, info.types[j]) or_return
- try_copy_string(i, buf, " | ") or_return
- try_copy_u64(i, buf, u64(info.bit_sizes[j])) or_return
+ if j > 0 { write_string(i, buf, ", ") or_return }
+ write_string (i, buf, name) or_return
+ write_string (i, buf, ": ") or_return
+ write_write_type(i, buf, info.types[j]) or_return
+ write_string (i, buf, " | ") or_return
+ write_u64 (i, buf, u64(info.bit_sizes[j])) or_return
}
- try_copy_byte(i, buf, '}') or_return
+ write_byte(i, buf, '}') or_return
case Type_Info_Simd_Vector:
- try_copy_string(i, buf, "#simd[") or_return
- try_copy_u64(i, buf, u64(info.count)) or_return
- try_copy_byte(i, buf, ']') or_return
- try_copy_write_type(i, buf, info.elem) or_return
+ write_string (i, buf, "#simd[") or_return
+ write_u64 (i, buf, u64(info.count)) or_return
+ write_byte (i, buf, ']') or_return
+ write_write_type(i, buf, info.elem) or_return
case Type_Info_Matrix:
- try_copy_string(i, buf, "matrix[") or_return
- try_copy_u64(i, buf, u64(info.row_count)) or_return
- try_copy_string(i, buf, ", ") or_return
- try_copy_u64(i, buf, u64(info.column_count)) or_return
- try_copy_string(i, buf, "]") or_return
- try_copy_write_type(i, buf, info.elem) or_return
+ if info.layout == .Row_Major {
+ write_string(i, buf, "#row_major ") or_return
+ }
+ write_string (i, buf, "matrix[") or_return
+ write_u64 (i, buf, u64(info.row_count)) or_return
+ write_string (i, buf, ", ") or_return
+ write_u64 (i, buf, u64(info.column_count)) or_return
+ write_string (i, buf, "]") or_return
+ write_write_type(i, buf, info.elem) or_return
}
return true
} \ No newline at end of file
diff --git a/core/container/handle_map/doc.odin b/core/container/handle_map/doc.odin
new file mode 100644
index 000000000..c1949ffdd
--- /dev/null
+++ b/core/container/handle_map/doc.odin
@@ -0,0 +1,56 @@
+/*
+Handle-based map using fixed-length arrays.
+
+Example:
+ import hm "core:container/handle_map"
+
+ Handle :: hm.Handle32
+
+ Entity :: struct {
+ handle: Handle,
+ pos: [2]f32,
+ }
+
+ { // static map
+ entities: hm.Static_Handle_Map(1024, Entity, Handle)
+
+ h1 := hm.add(&entities, Entity{pos = {1, 4}})
+ h2 := hm.add(&entities, Entity{pos = {9, 16}})
+
+ if e, ok := hm.get(&entities, h2); ok {
+ e.pos.x += 32
+ }
+
+ hm.remove(&entities, h1)
+
+ h3 := hm.add(&entities, Entity{pos = {6, 7}})
+
+ it := hm.iterator_make(&entities)
+ for e, h in hm.iterate(&it) {
+ e.pos += {1, 2}
+ }
+ }
+
+ { // dynamic map
+ entities: hm.Dynamic_Handle_Map(Entity, Handle)
+ hm.dynamic_init(&entities, context.allocator)
+ defer hm.dynamic_destroy(&entities)
+
+ h1 := hm.add(&entities, Entity{pos = {1, 4}})
+ h2 := hm.add(&entities, Entity{pos = {9, 16}})
+
+ if e, ok := hm.get(&entities, h2); ok {
+ e.pos.x += 32
+ }
+
+ hm.remove(&entities, h1)
+
+ h3 := hm.add(&entities, Entity{pos = {6, 7}})
+
+ it := hm.iterator_make(&entities)
+ for e, h in hm.iterate(&it) {
+ e.pos += {1, 2}
+ }
+ }
+*/
+package container_handle_map \ No newline at end of file
diff --git a/core/container/handle_map/dynamic_handle_map.odin b/core/container/handle_map/dynamic_handle_map.odin
new file mode 100644
index 000000000..067212a54
--- /dev/null
+++ b/core/container/handle_map/dynamic_handle_map.odin
@@ -0,0 +1,141 @@
+package container_handle_map
+
+import "base:runtime"
+import "base:builtin"
+import "base:intrinsics"
+@(require) import "core:container/xar"
+
+Dynamic_Handle_Map :: struct($T: typeid, $Handle_Type: typeid)
+ where
+ intrinsics.type_has_field(Handle_Type, "idx"),
+ intrinsics.type_has_field(Handle_Type, "gen"),
+ intrinsics.type_is_unsigned(intrinsics.type_field_type(Handle_Type, "idx")),
+ intrinsics.type_is_unsigned(intrinsics.type_field_type(Handle_Type, "gen")),
+ intrinsics.type_field_type(Handle_Type, "idx") == intrinsics.type_field_type(Handle_Type, "gen"),
+
+ intrinsics.type_has_field (T, "handle"),
+ intrinsics.type_field_type(T, "handle") == Handle_Type {
+
+ items: xar.Array(T, 4),
+ unused_items: xar.Array(u32, 4),
+}
+
+dynamic_init :: proc(m: ^$D/Dynamic_Handle_Map($T, $Handle_Type), allocator: runtime.Allocator) {
+ xar.init(&m.items, allocator)
+ xar.init(&m.unused_items, allocator)
+}
+
+dynamic_destroy :: proc(m: ^$D/Dynamic_Handle_Map($T, $Handle_Type)) {
+ xar.destroy(&m.unused_items)
+ xar.destroy(&m.items)
+}
+
+@(require_results)
+dynamic_add :: proc(m: ^$D/Dynamic_Handle_Map($T, $Handle_Type), item: T, loc := #caller_location) -> (handle: Handle_Type, err: runtime.Allocator_Error) {
+ if xar.len(m.unused_items) > 0 {
+ i := xar.pop(&m.unused_items)
+ ptr := xar.get_ptr_unsafe(&m.items, i)
+ prev_gen := ptr.handle.gen
+ ptr^ = item
+
+ ptr.handle.idx = auto_cast i
+ ptr.handle.gen = auto_cast (prev_gen + 1)
+ return ptr.handle, nil
+ }
+
+ if xar.len(m.items) == 0 {
+ // initialize the zero-value sentinel
+ xar.append(&m.items, T{}, loc) or_return
+ }
+
+ i := xar.append(&m.items, item, loc) or_return
+
+ ptr := xar.get_ptr_unsafe(&m.items, i)
+ ptr^ = item
+
+ ptr.handle.idx = auto_cast i
+ ptr.handle.gen = 1
+ return ptr.handle, nil
+}
+
+@(require_results)
+dynamic_get :: proc "contextless" (m: ^$D/Dynamic_Handle_Map($T, $Handle_Type), h: Handle_Type) -> (^T, bool) #optional_ok {
+ if h.idx <= 0 || int(u32(h.idx)) >= xar.len(m.items) {
+ return nil, false
+ }
+ if e := xar.get_ptr_unsafe(&m.items, h.idx); e.handle == h {
+ return e, true
+ }
+ return nil, false
+}
+
+dynamic_remove :: proc(m: ^$D/Dynamic_Handle_Map($T, $Handle_Type), h: Handle_Type, loc := #caller_location) -> (found: bool, err: runtime.Allocator_Error) {
+ if h.idx <= 0 || int(u32(h.idx)) >= xar.len(m.items) {
+ return false, nil
+ }
+
+ if item := xar.get_ptr(&m.items, h.idx); item.handle == h {
+ xar.append(&m.unused_items, u32(h.idx), loc) or_return
+ item.handle.idx = 0
+ return true, nil
+ }
+
+ return false, nil
+}
+
+@(require_results)
+dynamic_is_valid :: proc "contextless" (m: ^$D/Dynamic_Handle_Map($T, $Handle_Type), h: Handle_Type) -> bool {
+ return h.idx > 0 && int(u32(h.idx)) < xar.len(m.items) && xar.get_ptr_unsafe(&m.items, h.idx).handle == h
+}
+
+// Returns the number of possibly valid items in the handle map.
+@(require_results)
+dynamic_len :: proc "contextless" (m: $D/Dynamic_Handle_Map($T, $Handle_Type)) -> uint {
+ n := xar.len(m.items) - xar.len(m.unused_items)
+ return uint(n-1 if n > 0 else 0)
+}
+
+@(require_results)
+dynamic_cap :: proc "contextless" (m: $D/Dynamic_Handle_Map($T, $Handle_Type)) -> uint {
+ n := xar.cap(m.items)
+ return uint(n-1 if n > 0 else 0)
+}
+
+dynamic_clear :: proc "contextless" (m: ^$D/Dynamic_Handle_Map($T, $Handle_Type)) {
+ xar.clear(&m.items)
+ xar.clear(&m.unused_items)
+}
+
+
+// An iterator for a handle map.
+Dynamic_Handle_Map_Iterator :: struct($D: typeid) {
+ m: ^D,
+ index: int,
+}
+
+// Makes an iterator from a handle map.
+@(require_results)
+dynamic_iterator_make :: proc "contextless" (m: ^$D/Dynamic_Handle_Map($T, $Handle_Type)) -> Dynamic_Handle_Map_Iterator(D) {
+ return {m, 1}
+}
+
+/*
+ Iterate over a handle map. It will skip over unused item slots (e.g. handle.idx == 0).
+ Usage:
+ it := hm.dynamic_iterator_make(&the_dynamic_handle_map)
+ for item, handle in hm.iterate(&it) {
+ ...
+ }
+*/
+@(require_results)
+dynamic_iterate :: proc "contextless" (it: ^$DHI/Dynamic_Handle_Map_Iterator($D/Dynamic_Handle_Map($T, $Handle_Type))) -> (val: ^T, h: Handle_Type, ok: bool) {
+ for _ in it.index..<xar.len(it.m.items) {
+ e := xar.get_ptr_unsafe(&it.m.items, it.index)
+ it.index += 1
+
+ if e.handle.idx != 0 {
+ return e, e.handle, true
+ }
+ }
+ return
+} \ No newline at end of file
diff --git a/core/container/handle_map/static_handle_map.odin b/core/container/handle_map/static_handle_map.odin
new file mode 100644
index 000000000..f308c5e95
--- /dev/null
+++ b/core/container/handle_map/static_handle_map.odin
@@ -0,0 +1,221 @@
+package container_handle_map
+
+import "base:builtin"
+import "base:intrinsics"
+
+// Default 16-bit Handle type which can be used for handle maps which only need a maximum of 254 (1<<8 - 2) items
+Handle16 :: struct {
+ idx: u8,
+ gen: u8,
+}
+
+// Default 32-bit Handle type which can be used for handle maps which only need a maximum of 65534 (1<<16 - 2) items
+Handle32 :: struct {
+ idx: u16,
+ gen: u16,
+}
+
+// Default 64-bit Handle type which can be used for handle maps which only need a maximum of 4294967294 (1<<32 - 2) items
+Handle64 :: struct {
+ idx: u32,
+ gen: u32,
+}
+
+Static_Handle_Map :: struct($N: uint, $T: typeid, $Handle_Type: typeid)
+ where
+ 0 < N, N < uint(1<<31 - 1),
+
+ intrinsics.type_has_field(Handle_Type, "idx"),
+ intrinsics.type_has_field(Handle_Type, "gen"),
+ intrinsics.type_is_unsigned(intrinsics.type_field_type(Handle_Type, "idx")),
+ intrinsics.type_is_unsigned(intrinsics.type_field_type(Handle_Type, "gen")),
+ intrinsics.type_field_type(Handle_Type, "idx") == intrinsics.type_field_type(Handle_Type, "gen"),
+
+ N < uint(max(intrinsics.type_field_type(Handle_Type, "idx"))),
+
+ intrinsics.type_has_field (T, "handle"),
+ intrinsics.type_field_type(T, "handle") == Handle_Type {
+
+ // The zero element represent a zero-value sentinel (dummy value), allowing for `idx == 0` to mean a no-handle.
+ // This means the capacity is actually N-1 items.
+ items: [N]T,
+
+ used_len: u32, // How many of the items are in use
+ unused_len: u32, // Use to calculate the number of valid items
+ unused_items: [N]u32,
+ next_unused: u32,
+}
+
+
+// `add` a value of type `T` to the handle map. This will return a pointer to the item and an optional boolean to check for validity.
+@(require_results)
+static_add :: proc "contextless" (m: ^$H/Static_Handle_Map($N, $T, $Handle_Type), item: T) -> (handle: Handle_Type, ok: bool) #optional_ok {
+ if i := m.next_unused; i != 0 {
+ ptr := &m.items[i]
+
+ m.next_unused = m.unused_items[i]
+ m.unused_items[i] = 0
+
+ prev_gen := ptr.handle.gen
+ ptr^ = item
+
+ ptr.handle.idx = auto_cast i
+ ptr.handle.gen = auto_cast (prev_gen + 1)
+ m.unused_len -= 1
+ return ptr.handle, true
+ }
+
+ if m.used_len == 0 {
+ // initialize the zero-value sentinel
+ m.items[0] = {}
+ m.used_len += 1
+ }
+
+ if m.used_len == builtin.len(m.items) {
+ return {}, false
+ }
+
+ ptr := &m.items[m.used_len]
+ ptr^ = item
+
+ ptr.handle.idx = auto_cast m.used_len
+ ptr.handle.gen = 1
+ m.used_len += 1
+ return ptr.handle, true
+}
+
+// `get` a stable pointer of type `^T` by resolving the handle `h`. If the handle is not valid, then `nil, false` is returned.
+@(require_results)
+static_get :: proc "contextless" (m: ^$H/Static_Handle_Map($N, $T, $Handle_Type), h: Handle_Type) -> (^T, bool) #optional_ok {
+ if h.idx <= 0 || u32(h.idx) >= m.used_len {
+ return nil, false
+ }
+ if e := &m.items[h.idx]; e.handle == h {
+ return e, true
+ }
+ return nil, false
+}
+
+// `remove` an item from the handle map from the handle `h`.
+static_remove :: proc "contextless" (m: ^$H/Static_Handle_Map($N, $T, $Handle_Type), h: Handle_Type) -> bool {
+ if h.idx <= 0 || u32(h.idx) >= m.used_len {
+ return false
+ }
+
+ if item := &m.items[h.idx]; item.handle == h {
+ m.unused_items[h.idx] = m.next_unused
+ m.next_unused = u32(h.idx)
+ m.unused_len += 1
+ item.handle.idx = 0
+ return true
+ }
+
+ return false
+}
+
+// Returns true when the handle `h` is valid relating to the handle map.
+@(require_results)
+static_is_valid :: proc "contextless" (m: $H/Static_Handle_Map($N, $T, $Handle_Type), h: Handle_Type) -> bool {
+ return h.idx > 0 && u32(h.idx) < m.used_len && m.items[h.idx].handle == h
+}
+
+// Returns the number of possibly valid items in the handle map.
+@(require_results)
+static_len :: proc "contextless" (m: $H/Static_Handle_Map($N, $T, $Handle_Type)) -> uint {
+ n := uint(m.used_len) - uint(m.unused_len)
+ return n-1 if n > 0 else 0
+}
+
+// Returns the capacity of the items in a handle map.
+// This is equivalent to `N-1` as the zero value is reserved for the zero-value sentinel.
+@(require_results)
+static_cap :: proc "contextless" (m: $H/Static_Handle_Map($N, $T, $Handle_Type)) -> uint {
+ // We could just return `N` but I am doing this for clarity
+ return builtin.len(m.items)-1
+}
+
+// `clear` the handle map by zeroing all of the memory.
+// Internally this does not do `m^ = {}` but rather uses `intrinsics.mem_zero` explicitly improve performance.
+static_clear :: proc "contextless" (m: ^$H/Static_Handle_Map($N, $T, $Handle_Type)) {
+ intrinsics.mem_zero(m, size_of(m^))
+}
+
+// An iterator for a handle map.
+Static_Handle_Map_Iterator :: struct($H: typeid) {
+ m: ^H,
+ index: u32,
+}
+
+// Makes an iterator from a handle map.
+@(require_results)
+static_iterator_make :: proc "contextless" (m: ^$H/Static_Handle_Map($N, $T, $Handle_Type)) -> Static_Handle_Map_Iterator(H) {
+ return {m, 1}
+}
+
+/*
+ Iterate over a handle map. It will skip over unused item slots (e.g. handle.idx == 0).
+ Usage:
+ it := hm.iterator_make(&the_handle_map)
+ for item, handle in hm.iterate(&it) {
+ ...
+ }
+*/
+@(require_results)
+static_iterate :: proc "contextless" (it: ^$HI/Static_Handle_Map_Iterator($H/Static_Handle_Map($N, $T, $Handle_Type))) -> (val: ^T, h: Handle_Type, ok: bool) {
+ for _ in it.index..<it.m.used_len {
+ e := &it.m.items[it.index]
+ it.index += 1
+
+ if e.handle.idx != 0 {
+ return e, e.handle, true
+ }
+ }
+ return
+}
+
+
+
+add :: proc{
+ static_add,
+ dynamic_add,
+}
+
+get :: proc{
+ static_get,
+ dynamic_get,
+}
+
+remove :: proc{
+ static_remove,
+ dynamic_remove,
+}
+
+is_valid :: proc{
+ static_is_valid,
+ dynamic_is_valid,
+}
+
+len :: proc{
+ static_len,
+ dynamic_len,
+}
+
+cap :: proc{
+ static_cap,
+ dynamic_cap,
+}
+
+clear :: proc{
+ static_clear,
+ dynamic_clear,
+}
+
+iterator_make :: proc{
+ static_iterator_make,
+ dynamic_iterator_make,
+}
+
+iterate :: proc{
+ static_iterate,
+ dynamic_iterate,
+}
diff --git a/core/container/xar/xar.odin b/core/container/xar/xar.odin
index 07fdf5a15..556f93ee5 100644
--- a/core/container/xar/xar.odin
+++ b/core/container/xar/xar.odin
@@ -109,19 +109,19 @@ destroy :: proc(x: ^$X/Array($T, $SHIFT)) {
Resets the array's length to zero without freeing memory.
Allocated chunks are retained for reuse.
*/
-clear :: proc(x: ^$X/Array($T, $SHIFT)) {
+clear :: proc "contextless" (x: ^$X/Array($T, $SHIFT)) {
x.len = 0
}
// Returns the length of the exponential-array
@(require_results)
-len :: proc(x: $X/Array($T, $SHIFT)) -> int {
+len :: proc "contextless" (x: $X/Array($T, $SHIFT)) -> int {
return x.len
}
// Returns the number of allocated elements
@(require_results)
-cap :: proc(x: $X/Array($T, $SHIFT)) -> int {
+cap :: proc "contextless" (x: $X/Array($T, $SHIFT)) -> int {
#reverse for c, i in x.chunks {
if c != nil {
return 1 << (SHIFT + uint(i if i > 0 else 1))
@@ -132,7 +132,7 @@ cap :: proc(x: $X/Array($T, $SHIFT)) -> int {
// Internal: computes chunk index, element index within chunk, and chunk capacity for a given index.
@(require_results)
-_meta_get :: #force_inline proc($SHIFT: uint, index: uint) -> (chunk_idx, elem_idx, chunk_cap: uint) {
+_meta_get :: #force_inline proc "contextless" ($SHIFT: uint, index: uint) -> (chunk_idx, elem_idx, chunk_cap: uint) {
elem_idx = index
chunk_cap = uint(1) << SHIFT
chunk_idx = 0
@@ -206,6 +206,13 @@ get_ptr :: proc(x: ^$X/Array($T, $SHIFT), #any_int index: int, loc := #caller_lo
return &x.chunks[chunk_idx][elem_idx]
}
+// No bounds checking
+@(require_results)
+get_ptr_unsafe :: proc "contextless" (x: ^$X/Array($T, $SHIFT), #any_int index: int) -> (val: ^T) #no_bounds_check {
+ chunk_idx, elem_idx, _ := _meta_get(SHIFT, uint(index))
+ return &x.chunks[chunk_idx][elem_idx]
+}
+
/*
Set the element at the specified index to the given value.
diff --git a/core/crypto/_chacha20/ref/chacha20_ref.odin b/core/crypto/_chacha20/ref/chacha20_ref.odin
index c111c1c76..c4e6bca98 100644
--- a/core/crypto/_chacha20/ref/chacha20_ref.odin
+++ b/core/crypto/_chacha20/ref/chacha20_ref.odin
@@ -4,133 +4,68 @@ import "core:crypto/_chacha20"
import "core:encoding/endian"
import "core:math/bits"
-stream_blocks :: proc(ctx: ^_chacha20.Context, dst, src: []byte, nr_blocks: int) {
- // Enforce the maximum consumed keystream per IV.
- _chacha20.check_counter_limit(ctx, nr_blocks)
+// At least with LLVM21 force_inline produces identical perf to
+// manual inlining, yay.
+@(private)
+quarter_round :: #force_inline proc "contextless" (a, b, c, d: u32) -> (u32, u32, u32, u32) {
+ a, b, c, d := a, b, c, d
- dst, src := dst, src
- x := &ctx._s
- for n := 0; n < nr_blocks; n = n + 1 {
- x0, x1, x2, x3 :=
- _chacha20.SIGMA_0, _chacha20.SIGMA_1, _chacha20.SIGMA_2, _chacha20.SIGMA_3
- x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15 :=
- x[4], x[5], x[6], x[7], x[8], x[9], x[10], x[11], x[12], x[13], x[14], x[15]
+ a += b
+ d ~= a
+ d = bits.rotate_left32(d, 16)
- for i := _chacha20.ROUNDS; i > 0; i = i - 2 {
- // Even when forcing inlining manually inlining all of
- // these is decently faster.
+ c += d
+ b ~= c
+ b = bits.rotate_left32(b, 12)
- // quarterround(x, 0, 4, 8, 12)
- x0 += x4
- x12 ~= x0
- x12 = bits.rotate_left32(x12, 16)
- x8 += x12
- x4 ~= x8
- x4 = bits.rotate_left32(x4, 12)
- x0 += x4
- x12 ~= x0
- x12 = bits.rotate_left32(x12, 8)
- x8 += x12
- x4 ~= x8
- x4 = bits.rotate_left32(x4, 7)
+ a += b
+ d ~= a
+ d = bits.rotate_left32(d, 8)
- // quarterround(x, 1, 5, 9, 13)
- x1 += x5
- x13 ~= x1
- x13 = bits.rotate_left32(x13, 16)
- x9 += x13
- x5 ~= x9
- x5 = bits.rotate_left32(x5, 12)
- x1 += x5
- x13 ~= x1
- x13 = bits.rotate_left32(x13, 8)
- x9 += x13
- x5 ~= x9
- x5 = bits.rotate_left32(x5, 7)
+ c += d
+ b ~= c
+ b = bits.rotate_left32(b, 7)
- // quarterround(x, 2, 6, 10, 14)
- x2 += x6
- x14 ~= x2
- x14 = bits.rotate_left32(x14, 16)
- x10 += x14
- x6 ~= x10
- x6 = bits.rotate_left32(x6, 12)
- x2 += x6
- x14 ~= x2
- x14 = bits.rotate_left32(x14, 8)
- x10 += x14
- x6 ~= x10
- x6 = bits.rotate_left32(x6, 7)
+ return a, b, c, d
+}
- // quarterround(x, 3, 7, 11, 15)
- x3 += x7
- x15 ~= x3
- x15 = bits.rotate_left32(x15, 16)
- x11 += x15
- x7 ~= x11
- x7 = bits.rotate_left32(x7, 12)
- x3 += x7
- x15 ~= x3
- x15 = bits.rotate_left32(x15, 8)
- x11 += x15
- x7 ~= x11
- x7 = bits.rotate_left32(x7, 7)
+stream_blocks :: proc(ctx: ^_chacha20.Context, dst, src: []byte, nr_blocks: int) {
+ // Enforce the maximum consumed keystream per IV.
+ _chacha20.check_counter_limit(ctx, nr_blocks)
+
+ dst, src := dst, src
+ x := &ctx._s
- // quarterround(x, 0, 5, 10, 15)
- x0 += x5
- x15 ~= x0
- x15 = bits.rotate_left32(x15, 16)
- x10 += x15
- x5 ~= x10
- x5 = bits.rotate_left32(x5, 12)
- x0 += x5
- x15 ~= x0
- x15 = bits.rotate_left32(x15, 8)
- x10 += x15
- x5 ~= x10
- x5 = bits.rotate_left32(x5, 7)
- // quarterround(x, 1, 6, 11, 12)
- x1 += x6
- x12 ~= x1
- x12 = bits.rotate_left32(x12, 16)
- x11 += x12
- x6 ~= x11
- x6 = bits.rotate_left32(x6, 12)
- x1 += x6
- x12 ~= x1
- x12 = bits.rotate_left32(x12, 8)
- x11 += x12
- x6 ~= x11
- x6 = bits.rotate_left32(x6, 7)
+ // Filippo Valsorda made an observation that only one of the column
+ // round depends on the counter (s12), so it is worth precomputing
+ // and reusing across multiple blocks. As far as I know, only Go's
+ // chacha implementation does this.
- // quarterround(x, 2, 7, 8, 13)
- x2 += x7
- x13 ~= x2
- x13 = bits.rotate_left32(x13, 16)
- x8 += x13
- x7 ~= x8
- x7 = bits.rotate_left32(x7, 12)
- x2 += x7
- x13 ~= x2
- x13 = bits.rotate_left32(x13, 8)
- x8 += x13
- x7 ~= x8
- x7 = bits.rotate_left32(x7, 7)
+ p1, p5, p9, p13 := quarter_round(_chacha20.SIGMA_1, x[5], x[9], x[13])
+ p2, p6, p10, p14 := quarter_round(_chacha20.SIGMA_2, x[6], x[10], x[14])
+ p3, p7, p11, p15 := quarter_round(_chacha20.SIGMA_3, x[7], x[11], x[15])
- // quarterround(x, 3, 4, 9, 14)
- x3 += x4
- x14 ~= x3
- x14 = bits.rotate_left32(x14, 16)
- x9 += x14
- x4 ~= x9
- x4 = bits.rotate_left32(x4, 12)
- x3 += x4
- x14 ~= x3
- x14 = bits.rotate_left32(x14, 8)
- x9 += x14
- x4 ~= x9
- x4 = bits.rotate_left32(x4, 7)
+ for n := 0; n < nr_blocks; n = n + 1 {
+ // First column round that depends on the counter
+ p0, p4, p8, p12 := quarter_round(_chacha20.SIGMA_0, x[4], x[8], x[12])
+
+ // First diagonal round
+ x0, x5, x10, x15 := quarter_round(p0, p5, p10, p15)
+ x1, x6, x11, x12 := quarter_round(p1, p6, p11, p12)
+ x2, x7, x8, x13 := quarter_round(p2, p7, p8, p13)
+ x3, x4, x9, x14 := quarter_round(p3, p4, p9, p14)
+
+ for i := _chacha20.ROUNDS - 2; i > 0; i = i - 2 {
+ x0, x4, x8, x12 = quarter_round(x0, x4, x8, x12)
+ x1, x5, x9, x13 = quarter_round(x1, x5, x9, x13)
+ x2, x6, x10, x14 = quarter_round(x2, x6, x10, x14)
+ x3, x7, x11, x15 = quarter_round(x3, x7, x11, x15)
+
+ x0, x5, x10, x15 = quarter_round(x0, x5, x10, x15)
+ x1, x6, x11, x12 = quarter_round(x1, x6, x11, x12)
+ x2, x7, x8, x13 = quarter_round(x2, x7, x8, x13)
+ x3, x4, x9, x14 = quarter_round(x3, x4, x9, x14)
}
x0 += _chacha20.SIGMA_0
@@ -236,117 +171,15 @@ hchacha20 :: proc "contextless" (dst, key, iv: []byte) {
x15 := endian.unchecked_get_u32le(iv[12:16])
for i := _chacha20.ROUNDS; i > 0; i = i - 2 {
- // quarterround(x, 0, 4, 8, 12)
- x0 += x4
- x12 ~= x0
- x12 = bits.rotate_left32(x12, 16)
- x8 += x12
- x4 ~= x8
- x4 = bits.rotate_left32(x4, 12)
- x0 += x4
- x12 ~= x0
- x12 = bits.rotate_left32(x12, 8)
- x8 += x12
- x4 ~= x8
- x4 = bits.rotate_left32(x4, 7)
-
- // quarterround(x, 1, 5, 9, 13)
- x1 += x5
- x13 ~= x1
- x13 = bits.rotate_left32(x13, 16)
- x9 += x13
- x5 ~= x9
- x5 = bits.rotate_left32(x5, 12)
- x1 += x5
- x13 ~= x1
- x13 = bits.rotate_left32(x13, 8)
- x9 += x13
- x5 ~= x9
- x5 = bits.rotate_left32(x5, 7)
-
- // quarterround(x, 2, 6, 10, 14)
- x2 += x6
- x14 ~= x2
- x14 = bits.rotate_left32(x14, 16)
- x10 += x14
- x6 ~= x10
- x6 = bits.rotate_left32(x6, 12)
- x2 += x6
- x14 ~= x2
- x14 = bits.rotate_left32(x14, 8)
- x10 += x14
- x6 ~= x10
- x6 = bits.rotate_left32(x6, 7)
-
- // quarterround(x, 3, 7, 11, 15)
- x3 += x7
- x15 ~= x3
- x15 = bits.rotate_left32(x15, 16)
- x11 += x15
- x7 ~= x11
- x7 = bits.rotate_left32(x7, 12)
- x3 += x7
- x15 ~= x3
- x15 = bits.rotate_left32(x15, 8)
- x11 += x15
- x7 ~= x11
- x7 = bits.rotate_left32(x7, 7)
-
- // quarterround(x, 0, 5, 10, 15)
- x0 += x5
- x15 ~= x0
- x15 = bits.rotate_left32(x15, 16)
- x10 += x15
- x5 ~= x10
- x5 = bits.rotate_left32(x5, 12)
- x0 += x5
- x15 ~= x0
- x15 = bits.rotate_left32(x15, 8)
- x10 += x15
- x5 ~= x10
- x5 = bits.rotate_left32(x5, 7)
-
- // quarterround(x, 1, 6, 11, 12)
- x1 += x6
- x12 ~= x1
- x12 = bits.rotate_left32(x12, 16)
- x11 += x12
- x6 ~= x11
- x6 = bits.rotate_left32(x6, 12)
- x1 += x6
- x12 ~= x1
- x12 = bits.rotate_left32(x12, 8)
- x11 += x12
- x6 ~= x11
- x6 = bits.rotate_left32(x6, 7)
-
- // quarterround(x, 2, 7, 8, 13)
- x2 += x7
- x13 ~= x2
- x13 = bits.rotate_left32(x13, 16)
- x8 += x13
- x7 ~= x8
- x7 = bits.rotate_left32(x7, 12)
- x2 += x7
- x13 ~= x2
- x13 = bits.rotate_left32(x13, 8)
- x8 += x13
- x7 ~= x8
- x7 = bits.rotate_left32(x7, 7)
-
- // quarterround(x, 3, 4, 9, 14)
- x3 += x4
- x14 ~= x3
- x14 = bits.rotate_left32(x14, 16)
- x9 += x14
- x4 ~= x9
- x4 = bits.rotate_left32(x4, 12)
- x3 += x4
- x14 ~= x3
- x14 = bits.rotate_left32(x14, 8)
- x9 += x14
- x4 ~= x9
- x4 = bits.rotate_left32(x4, 7)
+ x0, x4, x8, x12 = quarter_round(x0, x4, x8, x12)
+ x1, x5, x9, x13 = quarter_round(x1, x5, x9, x13)
+ x2, x6, x10, x14 = quarter_round(x2, x6, x10, x14)
+ x3, x7, x11, x15 = quarter_round(x3, x7, x11, x15)
+
+ x0, x5, x10, x15 = quarter_round(x0, x5, x10, x15)
+ x1, x6, x11, x12 = quarter_round(x1, x6, x11, x12)
+ x2, x7, x8, x13 = quarter_round(x2, x7, x8, x13)
+ x3, x4, x9, x14 = quarter_round(x3, x4, x9, x14)
}
endian.unchecked_put_u32le(dst[0:4], x0)
diff --git a/core/crypto/_edwards25519/edwards25519.odin b/core/crypto/_edwards25519/edwards25519.odin
index d6f01d497..12192102d 100644
--- a/core/crypto/_edwards25519/edwards25519.odin
+++ b/core/crypto/_edwards25519/edwards25519.odin
@@ -195,7 +195,6 @@ ge_generator :: proc "contextless" (ge: ^Group_Element) {
ge_set(ge, &GE_BASEPOINT)
}
-@(private)
Addend_Group_Element :: struct {
y2_minus_x2: field.Loose_Field_Element, // t1
y2_plus_x2: field.Loose_Field_Element, // t3
@@ -203,7 +202,6 @@ Addend_Group_Element :: struct {
two_times_z2: field.Loose_Field_Element, // t5
}
-@(private)
ge_addend_set :: proc "contextless" (ge_a: ^Addend_Group_Element, ge: ^Group_Element) {
field.fe_sub(&ge_a.y2_minus_x2, &ge.y, &ge.x)
field.fe_add(&ge_a.y2_plus_x2, &ge.y, &ge.x)
@@ -420,6 +418,6 @@ ge_in_prime_order_subgroup_vartime :: proc "contextless" (ge: ^Group_Element) ->
// that is a ~50% speedup, and a lot of added complexity for something
// that is better solved by "just use ristretto255".
tmp: Group_Element = ---
- _ge_scalarmult(&tmp, ge, &SC_ELL, true)
+ ge_scalarmult_raw(&tmp, ge, &SC_ELL, true)
return ge_equal(&tmp, &GE_IDENTITY) == 1
}
diff --git a/core/crypto/_edwards25519/edwards25519_scalar_mul.odin b/core/crypto/_edwards25519/edwards25519_scalar_mul.odin
index 757a51257..d4ffa1075 100644
--- a/core/crypto/_edwards25519/edwards25519_scalar_mul.odin
+++ b/core/crypto/_edwards25519/edwards25519_scalar_mul.odin
@@ -1,130 +1,24 @@
package _edwards25519
+import "core:crypto"
import field "core:crypto/_fiat/field_scalar25519"
-import "core:math/bits"
+import subtle "core:crypto/_subtle"
import "core:mem"
-// GE_BASEPOINT_TABLE is 1 * G, ... 15 * G, in precomputed format.
-//
-// Note: When generating, the values were reduced to Tight_Field_Element
-// ranges, even though that is not required.
-@(private)
-GE_BASEPOINT_TABLE := Multiply_Table {
- {
- {62697248952638, 204681361388450, 631292143396476, 338455783676468, 1213667448819585},
- {1288382639258501, 245678601348599, 269427782077623, 1462984067271730, 137412439391563},
- {301289933810280, 1259582250014073, 1422107436869536, 796239922652654, 1953934009299142},
- {2, 0, 0, 0, 0},
- },
- {
- {1519297034332653, 1098796920435767, 1823476547744119, 808144629470969, 2110930855619772},
- {338005982828284, 1667856962156925, 100399270107451, 1604566703601691, 1950338038771369},
- {1920505767731247, 1443759578976892, 1659852098357048, 1484431291070208, 275018744912646},
- {763163817085987, 2195095074806923, 2167883174351839, 1868059999999762, 911071066608705},
- },
- {
- {960627541894068, 1314966688943942, 1126875971034044, 2059608312958945, 605975666152586},
- {1714478358025626, 2209607666607510, 1600912834284834, 496072478982142, 481970031861896},
- {851735079403194, 1088965826757164, 141569479297499, 602804610059257, 2004026468601520},
- {197585529552380, 324719066578543, 564481854250498, 1173818332764578, 35452976395676},
- },
- {
- {1152980410747203, 2196804280851952, 25745194962557, 1915167295473129, 1266299690309224},
- {809905889679060, 979732230071345, 1509972345538142, 188492426534402, 818965583123815},
- {997685409185036, 1451818320876327, 2126681166774509, 2000509606057528, 235432372486854},
- {887734189279642, 1460338685162044, 877378220074262, 102436391401299, 153369156847490},
- },
- {
- {2056621900836770, 1821657694132497, 1627986892909426, 1163363868678833, 1108873376459226},
- {1187697490593623, 1066539945237335, 885654531892000, 1357534489491782, 359370291392448},
- {1509033452137525, 1305318174298508, 613642471748944, 1987256352550234, 1044283663101541},
- {220105720697037, 387661783287620, 328296827867762, 360035589590664, 795213236824054},
- },
- {
- {1820794733038396, 1612235121681074, 757405923441402, 1094031020892801, 231025333128907},
- {1639067873254194, 1484176557946322, 300800382144789, 1329915446659183, 1211704578730455},
- {641900794791527, 1711751746971612, 179044712319955, 576455585963824, 1852617592509865},
- {743549047192397, 685091042550147, 1952415336873496, 1965124675654685, 513364998442917},
- },
- {
- {1004557076870448, 1762911374844520, 1330807633622723, 384072910939787, 953849032243810},
- {2178275058221458, 257933183722891, 376684351537894, 2010189102001786, 1981824297484148},
- {1332915663881114, 1286540505502549, 1741691283561518, 977214932156314, 1764059494778091},
- {429702949064027, 1368332611650677, 2019867176450999, 2212258376161746, 526160996742554},
- },
- {
- {2098932988258576, 2203688382075948, 2120400160059479, 1748488020948146, 1203264167282624},
- {677131386735829, 1850249298025188, 672782146532031, 2144145693078904, 2088656272813787},
- {1065622343976192, 1573853211848116, 223560413590068, 333846833073379, 27832122205830},
- {1781008836504573, 917619542051793, 544322748939913, 882577394308384, 1720521246471195},
- },
- {
- {660120928379860, 2081944024858618, 1878411111349191, 424587356517195, 2111317439894005},
- {1834193977811532, 1864164086863319, 797334633289424, 150410812403062, 2085177078466389},
- {1438117271371866, 783915531014482, 388731514584658, 292113935417795, 1945855002546714},
- {1678140823166658, 679103239148744, 614102761596238, 1052962498997885, 1863983323810390},
- },
- {
- {1690309392496233, 1116333140326275, 1377242323631039, 717196888780674, 82724646713353},
- {1722370213432106, 74265192976253, 264239578448472, 1714909985012994, 2216984958602173},
- {2010482366920922, 1294036471886319, 566466395005815, 1631955803657320, 1751698647538458},
- {1073230604155753, 1159087041338551, 1664057985455483, 127472702826203, 1339591128522371},
- },
- {
- {478053307175577, 2179515791720985, 21146535423512, 1831683844029536, 462805561553981},
- {1945267486565588, 1298536818409655, 2214511796262989, 1904981051429012, 252904800782086},
- {268945954671210, 222740425595395, 1208025911856230, 1080418823003555, 75929831922483},
- {1884784014268948, 643868448202966, 978736549726821, 46385971089796, 1296884812292320},
- },
- {
- {1861159462859103, 7077532564710, 963010365896826, 1938780006785270, 766241051941647},
- {1778966986051906, 1713995999765361, 1394565822271816, 1366699246468722, 1213407027149475},
- {1978989286560907, 2135084162045594, 1951565508865477, 671788336314416, 293123929458176},
- {902608944504080, 2167765718046481, 1285718473078022, 1222562171329269, 492109027844479},
- },
- {
- {1820807832746213, 1029220580458586, 1101997555432203, 1039081975563572, 202477981158221},
- {1866134980680205, 2222325502763386, 1830284629571201, 1046966214478970, 418381946936795},
- {1783460633291322, 1719505443254998, 1810489639976220, 877049370713018, 2187801198742619},
- {197118243000763, 305493867565736, 518814410156522, 1656246186645170, 901894734874934},
- },
- {
- {225454942125915, 478410476654509, 600524586037746, 643450007230715, 1018615928259319},
- {1733330584845708, 881092297970296, 507039890129464, 496397090721598, 2230888519577628},
- {690155664737246, 1010454785646677, 753170144375012, 1651277613844874, 1622648796364156},
- {1321310321891618, 1089655277873603, 235891750867089, 815878279563688, 1709264240047556},
- },
- {
- {805027036551342, 1387174275567452, 1156538511461704, 1465897486692171, 1208567094120903},
- {2228417017817483, 202885584970535, 2182114782271881, 2077405042592934, 1029684358182774},
- {460447547653983, 627817697755692, 524899434670834, 1228019344939427, 740684787777653},
- {849757462467675, 447476306919899, 422618957298818, 302134659227815, 675831828440895},
- },
-}
-
ge_scalarmult :: proc "contextless" (ge, p: ^Group_Element, sc: ^Scalar) {
tmp: field.Non_Montgomery_Domain_Field_Element
field.fe_from_montgomery(&tmp, sc)
- _ge_scalarmult(ge, p, &tmp)
+ ge_scalarmult_raw(ge, p, &tmp)
mem.zero_explicit(&tmp, size_of(tmp))
}
-ge_scalarmult_basepoint :: proc "contextless" (ge: ^Group_Element, sc: ^Scalar) {
- // Something like the comb method from "Fast and compact elliptic-curve
- // cryptography" Section 3.3, would be more performant, but more
- // complex.
- //
- // - https://eprint.iacr.org/2012/309
- ge_scalarmult(ge, &GE_BASEPOINT, sc)
-}
-
ge_scalarmult_vartime :: proc "contextless" (ge, p: ^Group_Element, sc: ^Scalar) {
tmp: field.Non_Montgomery_Domain_Field_Element
field.fe_from_montgomery(&tmp, sc)
- _ge_scalarmult(ge, p, &tmp, true)
+ ge_scalarmult_raw(ge, p, &tmp, true)
}
ge_double_scalarmult_basepoint_vartime :: proc "contextless" (
@@ -147,6 +41,12 @@ ge_double_scalarmult_basepoint_vartime :: proc "contextless" (
A_tbl: Multiply_Table = ---
mul_tbl_set(&A_tbl, A, &tmp_add)
+ when crypto.COMPACT_IMPLS == true {
+ G_tbl: Multiply_Table = ---
+ mul_tbl_set(&G_tbl, &GE_BASEPOINT, &tmp_add)
+ } else {
+ tmp_bp_addend: Basepoint_Addend_Group_Element = ---
+ }
sc_a, sc_b: field.Non_Montgomery_Domain_Field_Element
field.fe_from_montgomery(&sc_a, a)
@@ -170,21 +70,28 @@ ge_double_scalarmult_basepoint_vartime :: proc "contextless" (
ge_double(&tmp, &tmp, &tmp_dbl)
}
mul_tbl_add(&tmp, &A_tbl, hi_a, &tmp_add, &tmp_addend, true)
- mul_tbl_add(&tmp, &GE_BASEPOINT_TABLE, hi_b, &tmp_add, &tmp_addend, true)
+ when crypto.COMPACT_IMPLS == true {
+ mul_tbl_add(&tmp, &G_tbl, hi_b, &tmp_add, &tmp_addend, true)
+ } else {
+ mul_bp_tbl_add(&tmp, GE_BASEPOINT_TABLE, hi_b, &tmp_add, &tmp_bp_addend, true)
+ }
ge_double(&tmp, &tmp, &tmp_dbl)
ge_double(&tmp, &tmp, &tmp_dbl)
ge_double(&tmp, &tmp, &tmp_dbl)
ge_double(&tmp, &tmp, &tmp_dbl)
mul_tbl_add(&tmp, &A_tbl, lo_a, &tmp_add, &tmp_addend, true)
- mul_tbl_add(&tmp, &GE_BASEPOINT_TABLE, lo_b, &tmp_add, &tmp_addend, true)
+ when crypto.COMPACT_IMPLS == true {
+ mul_tbl_add(&tmp, &G_tbl, lo_b, &tmp_add, &tmp_addend, true)
+ } else {
+ mul_bp_tbl_add(&tmp, GE_BASEPOINT_TABLE, lo_b, &tmp_add, &tmp_bp_addend, true)
+ }
}
ge_set(ge, &tmp)
}
-@(private)
-_ge_scalarmult :: proc "contextless" (
+ge_scalarmult_raw :: proc "contextless" (
ge, p: ^Group_Element,
sc: ^field.Non_Montgomery_Domain_Field_Element,
unsafe_is_vartime := false,
@@ -281,8 +188,8 @@ mul_tbl_add :: proc "contextless" (
{2, 0, 0, 0, 0}, // z * 2
}
for i := u64(1); i < 16; i = i + 1 {
- _, ctrl := bits.sub_u64(0, (i ~ idx), 0)
- ge_addend_conditional_assign(tmp_addend, &tbl[i - 1], int(~ctrl) & 1)
+ ctrl := subtle.eq(i, idx)
+ ge_addend_conditional_assign(tmp_addend, &tbl[i - 1], int(ctrl))
}
ge_add_addend(ge, ge, tmp_addend, tmp_add)
}
diff --git a/core/crypto/_edwards25519/edwards25519_scalar_mul_base.odin b/core/crypto/_edwards25519/edwards25519_scalar_mul_base.odin
new file mode 100644
index 000000000..6820d618e
--- /dev/null
+++ b/core/crypto/_edwards25519/edwards25519_scalar_mul_base.odin
@@ -0,0 +1,147 @@
+package _edwards25519
+
+import "core:crypto"
+import field "core:crypto/_fiat/field_curve25519"
+import scalar "core:crypto/_fiat/field_scalar25519"
+import subtle "core:crypto/_subtle"
+import "core:mem"
+
+ge_scalarmult_basepoint :: proc "contextless" (ge: ^Group_Element, sc: ^Scalar) {
+ when crypto.COMPACT_IMPLS == true {
+ ge_scalarmult(ge, &GE_BASEPOINT, sc)
+ } else {
+ tmp_sc: scalar.Non_Montgomery_Domain_Field_Element
+ scalar.fe_from_montgomery(&tmp_sc, sc)
+
+ tmp_add: Add_Scratch = ---
+ tmp_addend: Basepoint_Addend_Group_Element = ---
+
+ ge_identity(ge)
+ for i in 0..<32 {
+ limb := i / 8
+ shift := uint(i & 7) * 8
+ limb_byte := tmp_sc[limb] >> shift
+
+ hi, lo := (limb_byte >> 4) & 0x0f, limb_byte & 0x0f
+ mul_bp_tbl_add(ge, &Gen_Multiply_Table_edwards25519_lo[i], lo, &tmp_add, &tmp_addend, false)
+ mul_bp_tbl_add(ge, &Gen_Multiply_Table_edwards25519_hi[i], hi, &tmp_add, &tmp_addend, false)
+ }
+
+ mem.zero_explicit(&tmp_sc, size_of(tmp_sc))
+ mem.zero_explicit(&tmp_add, size_of(Add_Scratch))
+ mem.zero_explicit(&tmp_addend, size_of(Basepoint_Addend_Group_Element))
+ }
+}
+
+when crypto.COMPACT_IMPLS == false {
+ @(private="file",rodata)
+ TWO_TIMES_Z2 := field.Loose_Field_Element{2, 0, 0, 0, 0}
+
+ @(private)
+ Basepoint_Addend_Group_Element :: struct {
+ y2_minus_x2: field.Loose_Field_Element, // t1
+ y2_plus_x2: field.Loose_Field_Element, // t3
+ k_times_t2: field.Tight_Field_Element, // t4
+ }
+
+ @(private)
+ Basepoint_Multiply_Table :: [15]Basepoint_Addend_Group_Element
+
+ @(private)
+ ge_bp_addend_conditional_assign :: proc "contextless" (ge_a, a: ^Basepoint_Addend_Group_Element, ctrl: int) {
+ field.fe_cond_select(&ge_a.y2_minus_x2, &ge_a.y2_minus_x2, &a.y2_minus_x2, ctrl)
+ field.fe_cond_select(&ge_a.y2_plus_x2, &ge_a.y2_plus_x2, &a.y2_plus_x2, ctrl)
+ field.fe_cond_select(&ge_a.k_times_t2, &ge_a.k_times_t2, &a.k_times_t2, ctrl)
+ }
+
+ @(private)
+ ge_add_bp_addend :: proc "contextless" (
+ ge, a: ^Group_Element,
+ b: ^Basepoint_Addend_Group_Element,
+ scratch: ^Add_Scratch,
+ ) {
+ // https://www.hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html#addition-add-2008-hwcd-3
+ // Assumptions: k=2*d, z = 1 (precomputation ftw)
+ //
+ // t0 = Y1-X1
+ // t1 = Y2-X2
+ // A = t0*t1
+ // t2 = Y1+X1
+ // t3 = Y2+X2
+ // B = t2*t3
+ // t4 = k*T2
+ // C = T1*t4
+ // t5 = 2*Z2
+ // D = Z1*t5
+ // E = B-A
+ // F = D-C
+ // G = D+C
+ // H = B+A
+ // X3 = E*F
+ // Y3 = G*H
+ // T3 = E*H
+ // Z3 = F*G
+ //
+ // In order to make the scalar multiply faster, the addend is provided
+ // as a `Addend_Group_Element` with t1, t3, t4, and t5 precomputed, as
+ // it is trivially obvious that those are the only values used by the
+ // formula that are directly dependent on `b`, and are only dependent
+ // on `b` and constants. This saves 1 sub, 2 adds, and 1 multiply,
+ // each time the intermediate representation can be reused.
+
+ A, B, C, D := &scratch.A, &scratch.B, &scratch.C, &scratch.D
+ E, F, G, H := &scratch.E, &scratch.F, &scratch.G, &scratch.H
+ t0, t2 := &scratch.t0, &scratch.t2
+
+ field.fe_sub(t0, &a.y, &a.x)
+ t1 := &b.y2_minus_x2
+ field.fe_carry_mul(A, t0, t1)
+ field.fe_add(t2, &a.y, &a.x)
+ t3 := &b.y2_plus_x2
+ field.fe_carry_mul(B, t2, t3)
+ t4 := &b.k_times_t2
+ field.fe_carry_mul(C, field.fe_relax_cast(&a.t), field.fe_relax_cast(t4))
+ field.fe_carry_mul(D, field.fe_relax_cast(&a.z), &TWO_TIMES_Z2)
+ field.fe_sub(E, B, A)
+ field.fe_sub(F, D, C)
+ field.fe_add(G, D, C)
+ field.fe_add(H, B, A)
+ field.fe_carry_mul(&ge.x, E, F)
+ field.fe_carry_mul(&ge.y, G, H)
+ field.fe_carry_mul(&ge.t, E, H)
+ field.fe_carry_mul(&ge.z, F, G)
+ }
+
+ @(private)
+ mul_bp_tbl_add :: proc "contextless" (
+ ge: ^Group_Element,
+ tbl: ^Basepoint_Multiply_Table,
+ idx: u64,
+ tmp_add: ^Add_Scratch,
+ tmp_addend: ^Basepoint_Addend_Group_Element,
+ unsafe_is_vartime: bool,
+ ) {
+ // Variable time lookup, with the addition omitted entirely if idx == 0.
+ if unsafe_is_vartime {
+ // Skip adding the point at infinity.
+ if idx != 0 {
+ ge_add_bp_addend(ge, ge, &tbl[idx-1], tmp_add)
+ }
+ return
+ }
+
+ // Constant time lookup.
+ tmp_addend^ = {
+ // Point at infinity (0, 1, 1, 0) in precomputed form, note
+ // that the precomputed tables rescale so that `Z = 1`.
+ {1, 0, 0, 0, 0}, // y - x
+ {1, 0, 0, 0, 0}, // y + x
+ {0, 0, 0, 0, 0}, // t * 2d
+ }
+ for i := u64(1); i < 16; i = i + 1 {
+ ctrl := subtle.eq(i, idx)
+ ge_bp_addend_conditional_assign(tmp_addend, &tbl[i - 1], int(ctrl))
+ }
+ ge_add_bp_addend(ge, ge, tmp_addend, tmp_add)
+ }
+}
diff --git a/core/crypto/_edwards25519/edwards25519_table.odin b/core/crypto/_edwards25519/edwards25519_table.odin
new file mode 100644
index 000000000..029b08418
--- /dev/null
+++ b/core/crypto/_edwards25519/edwards25519_table.odin
@@ -0,0 +1,4947 @@
+package _edwards25519
+
+/*
+ ------ GENERATED ------ DO NOT EDIT ------ GENERATED ------ DO NOT EDIT ------ GENERATED ------
+*/
+
+import "core:crypto"
+
+when crypto.COMPACT_IMPLS == false {
+ @(private,rodata)
+ Gen_Multiply_Table_edwards25519_lo := [32]Basepoint_Multiply_Table {
+ {
+ {
+ {4566296876323096, 4708280988758944, 2883091957081722, 4842055411046963, 5717267076190079},
+ {3540182452943730, 2497478415033846, 2521227595762870, 1462984067271729, 2389212253076811},
+ {301289933810280, 1259582250014073, 1422107436869536, 796239922652654, 1953934009299142},
+ },
+ {
+ {4966907458672021, 4936584233144657, 6114240989277698, 5254498676225494, 4146642117106832},
+ {3632771708514775, 790832306631235, 2067202295274102, 1995808275510000, 1566530869037010},
+ {748439484463711, 1033211726465151, 1396005112841647, 1611506220286469, 1972177495910992},
+ },
+ {
+ {4820158664987218, 4429624038632138, 3711242400124238, 3713328211397903, 3003390509798844},
+ {1601611775252272, 1720807796594148, 1132070835939856, 3512254832574799, 2147779492816910},
+ {1850748884277385, 1200145853858453, 1068094770532492, 672251375690438, 1586055907191707},
+ },
+ {
+ {3946190272469145, 6239505675006654, 5208669189437987, 5151632689063553, 5199813637784664},
+ {934282339813791, 1846903124198670, 1172395437954843, 1007037127761661, 1830588347719256},
+ {1121406372216585, 192876649532226, 190294192191717, 1994165897297032, 2245000007398739},
+ },
+ {
+ {4928851390486164, 2860263086157808, 4946162173083730, 5341365721927258, 4878154719998387},
+ {769950342298400, 2384754244604994, 3095885746880802, 3225892188161580, 2977876099231263},
+ {1086255230780037, 274979815921559, 1960002765731872, 929474102396301, 1190409889297339},
+ },
+ {
+ {4510980453010577, 4649810060060977, 4808503203819400, 5702468951241614, 3249489646904341},
+ {1388594989461809, 316767091099457, 2646098655878230, 1230079486801004, 1440737038838979},
+ {1181317918772081, 114573476638901, 262805072233344, 265712217171332, 294181933805782},
+ },
+ {
+ {4271167442657675, 2928511714391884, 4614310625181828, 3360446656227271, 5021391587042608},
+ {2916800678241215, 2065379846933858, 2622030924071124, 2602788184473875, 1233371373142984},
+ {965130719900578, 247011430587952, 526356006571389, 91986625355052, 2157223321444601},
+ },
+ {
+ {4325401225737414, 4534620752133203, 4768100597167576, 4751634318022197, 3282052041613534},
+ {4320419353804412, 4218074731744053, 957728544705548, 729906502578991, 2411634706750414},
+ {551790716293402, 1989538725166328, 801169423371717, 2052451893578887, 678432056995012},
+ },
+ {
+ {6229274597883966, 4185445767544427, 3794144352961029, 6271388400944242, 5801047593299399},
+ {1802695059464988, 1664899123557221, 2845359304426105, 2160434469266658, 3179370264440279},
+ {1381809363726107, 1430341051343062, 2061843536018959, 1551778050872521, 2036394857967624},
+ },
+ {
+ {3190293695332791, 4165728475672253, 4346255112396895, 3238346181288697, 4562115113555210},
+ {1569908045411451, 706723917266915, 1500941167088851, 2522858060362189, 3442327746686552},
+ {1454533688490200, 416156769327623, 1344514353803379, 1816391251363763, 259908591619060},
+ },
+ {
+ {4322190032257826, 3710718875543082, 5127771470387916, 5558932420078259, 4937587148103002},
+ {4222693909998302, 2779866139518454, 1619374932191226, 2207306624415883, 1169170329061080},
+ {893653801273833, 1168026499324677, 1242553501121234, 1306366254304474, 1086752658510815},
+ },
+ {
+ {4366666225767590, 5094682881462444, 5444160766003964, 2663859630225193, 4386427788371457},
+ {1548398643541286, 3090755542662214, 2368065889335542, 1878116023572279, 2384475613352909},
+ {1571032457823571, 1253760059932116, 665829584253800, 109400965270906, 981221002823741},
+ },
+ {
+ {6475278226276205, 4841626135259659, 5265997707342765, 5158696113477971, 4545898660066816},
+ {2465253816303469, 3191571337672685, 1159882208056013, 2569188183312765, 621213314200686},
+ {177130678690680, 1754759263300204, 1864311296286618, 1180675631479880, 1292726903152791},
+ },
+ {
+ {3248252964508250, 5061531253750778, 5542769770211014, 4619085244233909, 5311803534193606},
+ {2375959787421170, 2263885670311134, 2822409136676350, 3122669455540755, 1947192330052816},
+ {498660636760962, 1605652986893012, 893278769679967, 1769999239723039, 646478004325289},
+ },
+ {
+ {5574001150447352, 3524291821486207, 4161953422248557, 4327379335382018, 3442969602526468},
+ {1913163449625248, 2712579013977241, 2193883288642313, 1008900146920800, 1721983679009502},
+ {692896803108118, 500174642072499, 2068223309439677, 1162190621851337, 1426986007309901},
+ },
+ },
+ {
+ {
+ {5457238221803851, 3344133750480297, 5923374394087185, 3057477798065323, 3111028807187760},
+ {1368953770187805, 3042147450398169, 2689308289352409, 2142576377050579, 1932081720066286},
+ {1200766035879111, 20142053207432, 1465634435977050, 1645256912097844, 295121984874596},
+ },
+ {
+ {5563698449899448, 3838625675758736, 4715900944610621, 4227102525088801, 5170323687134830},
+ {1735718747031538, 1248237894295956, 1204753118328107, 976066523550493, 2317743583219840},
+ {1091990273418756, 1572899409348578, 80968014455247, 306009358661350, 1520450739132526},
+ },
+ {
+ {4403130087311393, 3013844998431429, 3939874146236762, 3074845922691006, 3159402582764738},
+ {3732317023121341, 1511153322193951, 3496143672676420, 2556587964178488, 2620936670181690},
+ {2047386910586836, 168470092900250, 1552838872594810, 340951180073789, 360819374702533},
+ },
+ {
+ {5483833971283375, 6215856366616550, 5092534899560758, 4707898440462492, 3093598134728534},
+ {1982622644432037, 2014393600336956, 2380709022489462, 3869592437614438, 2357094095599062},
+ {197561292938973, 454817274782871, 1963754960082318, 2113372252160468, 971377527342673},
+ },
+ {
+ {5235862574050758, 3926212577912309, 4434256219348056, 5854494381844745, 2810258686980493},
+ {2416499262514576, 2254927265442919, 3451304785234000, 1766155447043651, 1899238924683527},
+ {2103305098582922, 1960809151316468, 715134605001343, 1454892949167181, 40827143824949},
+ },
+ {
+ {4483855840793217, 3239143728269862, 4367394306679708, 4071397886477406, 3371105467700097},
+ {1239289043050193, 1744654158124578, 758702410031698, 4048562808759936, 2253402870349013},
+ {320153677847348, 939613871605645, 641883205761567, 1930009789398224, 329165806634126},
+ },
+ {
+ {4780421392687930, 3788635404873276, 3557012555097608, 4565073531580670, 4303176850668304},
+ {3232730304159378, 1242488692177892, 1251446316964684, 1086618677993530, 1961430968465772},
+ {833449923882501, 1750270368490475, 1123347002068295, 185477424765687, 278090826653186},
+ },
+ {
+ {3756645926444593, 3454896102689928, 5065739048841913, 4777932644822338, 3536143867460687},
+ {794524995833413, 1849907304548286, 2305148486158393, 1272368559505216, 1147304168324779},
+ {483048732424432, 2116063063343382, 30120189902313, 292451576741007, 1156379271702225},
+ },
+ {
+ {5884070579505425, 5535277330947453, 5603542025663670, 4776593639127153, 4995715838681551},
+ {2505290486961759, 2288457607049763, 1322694247668132, 2996684795874985, 1441775943403867},
+ {1862130357601747, 1576563056403606, 1053598539514442, 836379099899856, 1745075449649052},
+ },
+ {
+ {4271432792719273, 4354519732898601, 3841949260311002, 4278872468826501, 3182588946344969},
+ {994086190120795, 2265566763472579, 1778668799717474, 1759565368702851, 1705243805775865},
+ {208457126969992, 1306788169067141, 1504881061177412, 778305094530678, 286650467791603},
+ },
+ {
+ {3704308183084302, 4667642921024280, 3735446294701327, 4710970560312866, 5219863835152358},
+ {1155946475009464, 1378854908418478, 3050476655608427, 738141412602796, 1805371589338096},
+ {1627667107954997, 2038498693464737, 380348381597727, 693747096546728, 1241364634477378},
+ },
+ {
+ {4610118268113321, 3236474426265456, 4804410568671572, 4099577866548348, 3504102383946080},
+ {748123900738723, 2239140288387656, 322477057520882, 2644973441419796, 1290933190145308},
+ {2218076336525385, 339947754397137, 1735892619490, 1441988709036711, 932991353908008},
+ },
+ {
+ {5176295056640358, 3403895808063209, 3860193783232080, 4018349594328251, 4528337169205809},
+ {2638983432827646, 2268258692789757, 3287339174338050, 1299412654822337, 936917254750873},
+ {430804656367208, 1812394904738259, 550528638373630, 2103769550939254, 443986453677108},
+ },
+ {
+ {4019814909194368, 2925457503142305, 3944973873459804, 4250278944002558, 4031746156495663},
+ {3925945607985574, 2164215477088927, 2286513560718006, 3385980103702156, 1734257170111047},
+ {38890723392351, 853701573154564, 966467672212375, 417321296433946, 554926061377915},
+ },
+ {
+ {5000002949084352, 4896484517581292, 5148976024567894, 4815058842461170, 4176010608048328},
+ {1720782684885150, 798987029915204, 1610161967147136, 3970529737234552, 936254274515738},
+ {562662523022136, 737396420860869, 1964828496205405, 271079414894445, 1393713695470127},
+ },
+ },
+ {
+ {
+ {4641332589184683, 2958470737602587, 5890637714236266, 6469243441056846, 3636576929381593},
+ {3180171966714267, 2147692869914563, 1455665844462196, 1986737809425946, 2437006863943337},
+ {481144981981577, 2053319313589856, 2065402289827512, 617954271490316, 1106602634668125},
+ },
+ {
+ {5160989980743332, 3250299780570808, 5495492964276292, 5314069834477255, 2594939618294032},
+ {2948097833334040, 3145099472726142, 1148636718636008, 2278533891034865, 2203955659340680},
+ {791736669492960, 934767652997115, 824656780392914, 1759463253018643, 361530362383518},
+ },
+ {
+ {5791086827335700, 4467111755065554, 3804728204617233, 6168459157050691, 3376804788950489},
+ {2022541353055578, 4346500076272714, 3802807888710933, 2494585331103411, 2947785218648809},
+ {677434665154918, 989582503122485, 1817429540898386, 1052904935475344, 1143826298169798},
+ },
+ {
+ {3025160502526487, 6318980957908565, 4867373065037870, 5043229614440699, 3035080247933683},
+ {2619066141993637, 2570231002607651, 2947429167440602, 2885885471266079, 2276381426249673},
+ {180820816194166, 168937968377394, 748416242794470, 1227281252254508, 1567587861004268},
+ },
+ {
+ {4236540720225255, 5582763806770724, 3307821162947907, 3911758370168910, 3340328882710774},
+ {2730575372268893, 2062896624554806, 2951191072970647, 2609899222113120, 1277310261461760},
+ {580736401511151, 1842931091388998, 1177201471228238, 2075460256527244, 1301133425678027},
+ },
+ {
+ {3547095551954881, 3966542127392273, 5049182669833076, 6538011303633046, 3765047903698852},
+ {1515728832059163, 1575261009617579, 1510246567196186, 2442877836294952, 2368461529974388},
+ {230710545179830, 30821514358353, 760704303452229, 390668103790604, 573437871383156},
+ },
+ {
+ {4354054137171033, 3822632479902001, 4538296533915119, 4245013553492583, 4574238179641958},
+ {3421179921230875, 2514967047430861, 4274701112739695, 3071700566936367, 4275698278559832},
+ {894132856735058, 548675863558441, 845349339503395, 1942269668326667, 1615682209874691},
+ },
+ {
+ {5296988143897756, 3567256897335281, 4224086813027664, 4153625766737702, 4841869104592905},
+ {3539470031223082, 1222355136884919, 1846481788678694, 1150426571265110, 1613523400722047},
+ {550201530671806, 778605267108140, 2063911101902983, 115500557286349, 2041641272971022},
+ },
+ {
+ {2639140850252425, 3988225053741778, 4109492541046027, 4467731762307139, 4788525019017799},
+ {1956266817271455, 2914237312642832, 2018010448016151, 4042065159660719, 3422400064417223},
+ {1185820244523867, 953640094456191, 1426524678517613, 1191533398208458, 1993578549159852},
+ },
+ {
+ {4724762102005390, 3941768459309593, 3168985852401486, 5230753070525336, 5120855380354436},
+ {2162922301975048, 2584871642802941, 2903836488265486, 2034914383000476, 1973107217149520},
+ {1225503059018859, 1744932331605022, 393061606917651, 2045141059558447, 1187823695528756},
+ },
+ {
+ {3873867956612972, 5901886943623014, 4214442512189194, 3726570129804851, 4003114175771373},
+ {2499971111138236, 1856344473990516, 2851460465748678, 1490509710033167, 3414551741933391},
+ {1569106592395768, 1670704805332568, 2011861983976474, 822492307064908, 1138495702641636},
+ },
+ {
+ {4611233673112936, 4109919865110418, 3874636387071312, 4304609757893158, 4158539624577373},
+ {3888656531434102, 3371559592472684, 2495053387333630, 3579436360572308, 1114431352259831},
+ {2209993507106795, 1762615018349199, 1687296090930185, 9491601628221, 870532128794902},
+ },
+ {
+ {4833972836221169, 5399132877586271, 4606616407949355, 4080860583790927, 4239964386503137},
+ {1305913677624121, 3558400184075999, 3275823038503467, 3454063433790229, 1309514508446881},
+ {1566723549675548, 1397175496983691, 504231980459915, 306990234666329, 1744893526714441},
+ },
+ {
+ {4014795958128859, 5054570465100501, 3081378639295577, 5833550217358299, 3899560884622359},
+ {972376391789061, 1850852472634117, 2719443704140285, 2186622623776515, 3209686661433313},
+ {2171782442569495, 1594104418173184, 1848207566547320, 2195471209947031, 1091928745815642},
+ },
+ {
+ {4698583634348737, 4028817484747578, 3922491723357167, 4921897981297279, 5070174707952522},
+ {3952749170677737, 509151538148928, 2600240333845125, 2270835069234179, 3790913978189516},
+ {1587050028613976, 1757976429633698, 440367736554514, 102469500615778, 1293087093446941},
+ },
+ },
+ {
+ {
+ {4765314848902696, 4047154143755239, 3748677840535530, 5003339347891547, 4892630780044264},
+ {717255318455100, 519313764361315, 2080406977303708, 541981206705521, 774328150311600},
+ {1997217696294013, 1717306351628065, 1684313917746180, 1644426076011410, 1857378133465451},
+ },
+ {
+ {4274106452868777, 5229895690942370, 4818944681819138, 3310533142834467, 5951800763431172},
+ {3727234538477877, 2328731709971226, 3368528843456914, 2002544139318041, 2977347647489186},
+ {1710065158525665, 1895094923036397, 123988286168546, 1145519900776355, 1607510767693874},
+ },
+ {
+ {6052094801116259, 4945910156597034, 3249872360685630, 5056653985755776, 5148423953746665},
+ {2813405189107769, 1071733543815036, 2383296312486238, 1946868434569998, 3079937947649451},
+ {1445526537029440, 2225519789662536, 914628859347385, 1064754194555068, 1660295614401091},
+ },
+ {
+ {5380526401591301, 2806418790173460, 3263856123526812, 3091761635239858, 3666299153992924},
+ {3451490036797185, 2275827949507588, 2318438102929588, 2309425969971222, 2816893781664854},
+ {703047626104145, 1266841406201770, 165556500219173, 486991595001879, 1011325891650656},
+ },
+ {
+ {4838486554794399, 4993110726592022, 4632760493337220, 3972608926828727, 2871500009334501},
+ {1622861044480487, 1156394801573634, 4120932379100752, 2578903799462977, 2095342781472283},
+ {1646545795166119, 1758370782583567, 714746174550637, 1472693650165135, 898994790308209},
+ },
+ {
+ {4062996033667232, 5572569452904097, 4793202602203933, 4240755857296838, 5367161970768862},
+ {2585203586724508, 2547572356138185, 1693106465353609, 912330357530760, 2723035471635610},
+ {906282429780072, 2108672665779781, 432396390473936, 150625823801893, 1708930497638539},
+ },
+ {
+ {3731585820952935, 6242481486437170, 4572245823847061, 4398306869785574, 5751262444905966},
+ {925664675702309, 2273216662253932, 4083236455546587, 601157008940112, 2623617868729744},
+ {52035296774456, 939969390708103, 312023458773250, 59873523517659, 1231345905848899},
+ },
+ {
+ {4632957969763174, 4184611431390023, 5680349018170176, 4901639977232284, 5674379295460919},
+ {2895154920100990, 2541986621181021, 2013561737429022, 2571447883196794, 2645536492181409},
+ {2051980782668029, 121859921510665, 2048329875753063, 1235229850149665, 519062146124755},
+ },
+ {
+ {4207228868621988, 4953881226819951, 4139842782246336, 4298958943276773, 3359727402165629},
+ {947983997565204, 1512975730400883, 4017071259732234, 765863411195419, 2287620622340759},
+ {2248717923990509, 953644234015146, 118881148429301, 1244045737066019, 519708790776758},
+ },
+ {
+ {5697680122778496, 6228365759267448, 4861216723530833, 4702869303488893, 5552489090348314},
+ {1440754265571108, 2717772629254708, 2851948946836421, 3389483713931559, 1448786922664578},
+ {843777949621211, 1435525643946674, 1087149831109219, 1794919173070415, 1112222323032617},
+ },
+ {
+ {5102037877608319, 4652686712219969, 3897951345871191, 3585818368367414, 5206224086433126},
+ {1659077274827511, 3292962448731851, 3877468219103951, 1516723029470630, 2756801757695330},
+ {1080269027468022, 217052522911549, 1656325362355128, 1627927536138189, 547476742306034},
+ },
+ {
+ {4629572650764889, 5482991583454262, 5026118951697692, 3386284302539994, 4183091862778757},
+ {4049116095173975, 2853051218008192, 874408124299498, 2811479573934506, 3061819813989639},
+ {1673853233469462, 2069508754540826, 444570721431342, 318669192295723, 1286647860911061},
+ },
+ {
+ {5230179910306733, 4570722910725029, 2679420725332655, 3219299251684998, 5101899978929471},
+ {3368016050367733, 1864179846991811, 2025579249953153, 2185933453914170, 3081358815633795},
+ {1120488984292940, 268864491510849, 230793761352121, 54153081190951, 1544798876643945},
+ },
+ {
+ {4594071143939477, 4032573207368795, 3586642054806445, 2633280388282362, 4204685405148786},
+ {3215023450765629, 1989745848107067, 2317683847606295, 2073505048594828, 792770882411102},
+ {213368529611304, 716996641453362, 1913278462832177, 1585475497182388, 563601091454134},
+ },
+ {
+ {2835663672936090, 4829603014808807, 3487022863582034, 2792788055117753, 4407939774570859},
+ {1893732627269868, 2896260158734549, 1988156739597398, 2606708976150985, 1947694156880429},
+ {1687313081048019, 7705508083870, 487993091259388, 560742684726806, 779697153923449},
+ },
+ },
+ {
+ {
+ {4089455896800313, 6013733676182565, 5409863301562555, 4072864011490980, 5068974752046796},
+ {3859970785658325, 2667608874045675, 1350468408164765, 2038620059057678, 3278704299674360},
+ {578027192365650, 2034800251375322, 2128954087207123, 478816193810521, 2196171989962750},
+ },
+ {
+ {4965788985850512, 4036616547844474, 3863134115336615, 3555738077628787, 5211189187689919},
+ {1633188840273120, 3104586986058956, 1548762607215795, 1266275218902681, 3359018017010381},
+ {1038829280972848, 38176604650029, 753193246598573, 1136076426528122, 595709990562434},
+ },
+ {
+ {4508300680732578, 6151240693672842, 5551152629612579, 4175434827081223, 4710569942272560},
+ {3660251634545082, 2194984964010832, 2198361797561729, 1061962440055713, 1645147963442934},
+ {1750479161778571, 1362553355169293, 1891721260220598, 966109370862782, 1024913988299801},
+ },
+ {
+ {5140408161043668, 3514001525352806, 4894551007701094, 3915220506382540, 5065550949127901},
+ {2464498862816952, 1117950018299774, 1873945661751056, 3655602735669306, 2382695896337945},
+ {520731594438141, 1446301499955692, 273753264629267, 1565101517999256, 1019411827004672},
+ },
+ {
+ {3716451775537782, 3735537109406964, 3771250375020764, 3413229645449032, 4909514625550472},
+ {3178327305714638, 3443653291096626, 734233225181170, 2435838701226518, 4042225960010590},
+ {996126634382301, 796204125879525, 127517800546509, 344155944689303, 615279846169038},
+ },
+ {
+ {5126516964784293, 5722588804459529, 5788457340217086, 5474101689079853, 4854624835487584},
+ {2990523894660505, 2188666632415295, 1961313708559162, 1506545807547587, 3403101452654988},
+ {2067814584765580, 1677855129927492, 2086109782475197, 235286517313238, 1416314046739645},
+ },
+ {
+ {5182089550298661, 4268457398409278, 4594577010420123, 5530431534605076, 5118871120313016},
+ {2838644076315587, 2559244195637442, 458399356043425, 2853867838192310, 3280348017100490},
+ {301225714012278, 1094837270268560, 1202288391010439, 644352775178361, 1647055902137983},
+ },
+ {
+ {5639203700568665, 3935121894170720, 5272747431747178, 4338487944274660, 5404045310490874},
+ {1210746697896459, 1416608304244708, 2938287290903104, 3496931005119382, 3303038150540984},
+ {1971518477615628, 401909519527336, 448627091057375, 1409486868273821, 1214789035034363},
+ },
+ {
+ {5099963449143288, 5521329395009146, 5925708408867572, 4221709339736212, 4612387286592975},
+ {1894554173291056, 3439387781984292, 2885767225889068, 620075308547710, 1923191105660691},
+ {2193142205372254, 2249202758109308, 136771833945490, 2136446252990850, 1913453314551631},
+ },
+ {
+ {3519416739470062, 5800837512824035, 5629830750568439, 3858242948002290, 4384918516791051},
+ {1031287572005306, 2743053635058531, 1307200063174499, 886968262945288, 322139622562321},
+ {1603190765881197, 1131168289986667, 1851325240689452, 1811918922856612, 1688789764638099},
+ },
+ {
+ {5675121438563826, 3813646429348722, 6155915780969232, 4550135853787182, 3281226794470063},
+ {1227916715088978, 3565721991039408, 2825753167382054, 446650609575830, 3201068492916497},
+ {465975618381320, 1757724298980204, 2172737911773281, 1844204403201116, 367200393612929},
+ },
+ {
+ {4053304559591831, 4763567221009860, 6256382270106074, 5569940279565028, 4297628970970611},
+ {522695684014153, 2454309386747442, 1812320598717590, 1790060723730286, 513480358702681},
+ {1695032670616248, 1588968761785032, 699742416328216, 547685855993128, 1790235994988743},
+ },
+ {
+ {3776137870634381, 3800031162558423, 5542451196069607, 4330978223940644, 5450131593237007},
+ {3411403847639229, 1506626399353463, 2324339461338721, 1195836709245006, 2829489236982793},
+ {263703254267006, 1082588170565097, 2024394221181425, 46543794553459, 2110417854356146},
+ },
+ {
+ {5712489756196259, 4857601027744288, 4243491518458906, 4901936639181452, 4456074323550475},
+ {2520601556174181, 1164555774547222, 2770926848501726, 3208860864993280, 497236288525621},
+ {247502314830666, 1623351904090299, 1162047175878913, 1697644630093486, 776531516340321},
+ },
+ {
+ {2686302584388573, 3722578779150130, 6045187633044733, 3467509394641570, 3302975571798606},
+ {2408284467064191, 2899235622132542, 2270755745458389, 1460665123127634, 2622446416668442},
+ {625008843842459, 305089228555404, 1124988453243439, 123919845855976, 788637610781258},
+ },
+ },
+ {
+ {
+ {3297030136943183, 5321806228516302, 2882313002761349, 3923846342683379, 5310803644932932},
+ {1364039144731711, 1897497433586190, 2203097701135459, 2397261210496499, 1349844460790698},
+ {439961968385997, 386362664488986, 1382706320807688, 309894000125359, 2207801346498567},
+ },
+ {
+ {4255565910583278, 4673673686605660, 3392924072653217, 3737219707166220, 3825562634713972},
+ {3480804500082836, 3172443782216110, 2375775707596425, 2933223806901024, 1400559197080972},
+ {729905708611432, 1270323270673202, 123353058984288, 426460209632942, 2195574535456672},
+ },
+ {
+ {4013408251151364, 5086960474897299, 3838506203370739, 4408856413264508, 3422492183371019},
+ {1271140255321216, 2044363183174497, 2303925201319937, 3696920060379952, 3194341800024331},
+ {871476219910823, 1878769545097794, 2241832391238412, 548957640601001, 690047440233174},
+ },
+ {
+ {3251428812313581, 5636436335863895, 4336541488202699, 4972942980386107, 5182382616078529},
+ {2548994545820755, 1366347803776819, 3552985325930849, 561849853336293, 1533554921345731},
+ {2189427607417022, 699801937082607, 412764402319267, 1478091893643349, 2244675696854460},
+ },
+ {
+ {5012160783311108, 5470528103057159, 4488517614835378, 2676343672262544, 4341072770671390},
+ {3964091869651792, 2456213404310121, 3657538451018088, 2660781114515010, 3112882032961968},
+ {221245220129925, 1156020201681217, 491145634799213, 542422431960839, 828100817819207},
+ },
+ {
+ {2810886626483710, 5076777331583206, 6133336711186896, 3651619527147841, 3898754191951285},
+ {2405556784925632, 1299874139923976, 2644898978945750, 1058234455773021, 996989038681183},
+ {1887963056288059, 228507035730124, 1468368348640282, 930557653420194, 613513962454686},
+ },
+ {
+ {5579887344422086, 5618055197913529, 4690896687085975, 4754046511662615, 4136987326235786},
+ {1224529808187534, 1577022856702685, 2206946542980843, 625883007765001, 2531730607197406},
+ {902497362940219, 76749815795675, 1657927525633846, 1420238379745202, 1340321636548352},
+ },
+ {
+ {5132340287409247, 4194838312213087, 4971385975164381, 5596941055673869, 4739013486883497},
+ {1129576631190765, 3533793823712575, 996844254743017, 2509676177174497, 3402650555740265},
+ {237425418909360, 469614029179605, 1512389769174935, 1241726368345357, 441602891065214},
+ },
+ {
+ {5266234055777943, 3166499093963215, 4159587332862448, 3232787848503690, 6261694765772425},
+ {2508069708566903, 2982887287210837, 1712829089863354, 1739545432690564, 1853100260794477},
+ {4642168584761, 1314096799362798, 1620739012635580, 444075187404753, 76135520441225},
+ },
+ {
+ {5167832514805982, 5410004641404511, 3809624149844670, 4773980049888932, 3778278866830004},
+ {1717340294466846, 3145810307460687, 1904170181110298, 3950114374260626, 2248427553137502},
+ {1356583144121446, 1439603152129038, 880464721166116, 426511648446184, 1044401386572766},
+ },
+ {
+ {3827273464157640, 5470853620720833, 4235776821907793, 5432246822532161, 4674460658804935},
+ {3682691082267936, 1935676112917301, 3170276622979891, 2876033130676637, 1596266630249199},
+ {1484505136430423, 343818915658679, 1066931341976591, 1574952097402529, 895157643469052},
+ },
+ {
+ {6636210482709397, 2566644085561849, 4278449441656290, 5708653335234549, 6540605640281063},
+ {2193735258244385, 2265742668153213, 2801601661178220, 1573679250261669, 2218164822512395},
+ {125908919015544, 908539856510216, 254196493329521, 1841783557943867, 1826956209112337},
+ },
+ {
+ {4015848574593688, 5374261932338028, 4759505940569418, 5686761164384680, 3410517186063399},
+ {1218465765165754, 1222399589933778, 4149598104194804, 2307999947285970, 2530437726498307},
+ {1352017428769842, 1226345478088737, 1834808987089176, 171935268241134, 1252599135760918},
+ },
+ {
+ {4391913968320982, 5643346087738336, 3260878495624279, 6345563729780486, 6485738780527396},
+ {269241043449612, 1713401415896622, 3060740655644691, 2228155591500882, 2273523243235430},
+ {994025955714788, 1395495501299355, 1717525291885154, 64780760930213, 1492125616744822},
+ },
+ {
+ {4496571738540020, 6137682561017990, 4165346179942417, 4589212756752962, 5249152453870163},
+ {2859457773452122, 2592803086422694, 761249806099561, 4355723617152898, 2688955778843975},
+ {686675614020084, 1129369471718576, 1361332769753183, 814390480194826, 1958437091006724},
+ },
+ },
+ {
+ {
+ {4212554477605918, 5000640585259457, 4161632664968341, 3523231950682073, 4471580181706187},
+ {3988217766743784, 726531315520507, 1833335034432527, 1629442561574747, 2876218732971333},
+ {1537037379417136, 1358865369268262, 2130838645654099, 828733687040705, 1999987652890901},
+ },
+ {
+ {4063362146350583, 3753681832692920, 4465563314774246, 4863172707090131, 4539970192419610},
+ {629042105241795, 1098854999137608, 887281544569320, 3674901833560025, 2259711072636808},
+ {218907117361280, 1209298913016966, 1944312619096112, 1130690631451061, 1342327389191701},
+ },
+ {
+ {4482501699248035, 5851772807709469, 4424655942309844, 5930138373494266, 4947793108696645},
+ {1369976867854685, 1396479602419169, 4017456468084104, 2203659200586298, 3250127649802489},
+ {784210426627951, 918204562375674, 1284546780452985, 1324534636134684, 1872449409642708},
+ },
+ {
+ {4153660020381144, 4256288935750983, 3877646875253483, 3225329557085126, 4327087498998152},
+ {2571438643225542, 2848082470493653, 2037902696412607, 1557219121643918, 341938082688094},
+ {1371853944110545, 1042332820512553, 1949855697918254, 1791195775521505, 37487364849293},
+ },
+ {
+ {4334516943269102, 4531429052909917, 4649254694042464, 3942327023530758, 6368860137043973},
+ {687200189577836, 1082536651125675, 2896024754556794, 2592723009743198, 2595381160432643},
+ {1059729620568824, 2163709103470266, 1440302280256872, 1769143160546397, 869830310425069},
+ },
+ {
+ {4276621734726805, 4930548302820644, 2846933097770719, 4975460488256465, 2852121493098246},
+ {3861316033464273, 777277757338816, 2101121130363987, 550762194946473, 1905542338659364},
+ {598474602406721, 1468128276358244, 1191923149557635, 1501376424093216, 1281662691293476},
+ },
+ {
+ {2971320059272372, 4896980339002840, 4635950028233875, 3795071084495975, 4071343109483907},
+ {1721138489890688, 1264336102277790, 2684864359106535, 1359988423149465, 3813671107094695},
+ {396397949784152, 1811354474471839, 1362679985304303, 2117033964846756, 498041172552279},
+ },
+ {
+ {5154223559778472, 3389351102095821, 4377023217300786, 3977457826906518, 4386692778803043},
+ {1812471844975748, 1856491995543149, 126579494584102, 3288044672967868, 1975108050082549},
+ {522584000310195, 1241762481390450, 1743702789495384, 2227404127826575, 1686746002148897},
+ },
+ {
+ {4080889153606423, 5116319911316914, 4006591728131774, 4350736921528591, 4198995697088691},
+ {3932341308304797, 1612580099028530, 2937385230920440, 1836672506516533, 517164940700103},
+ {1413348606155183, 810499206093511, 1138057743946731, 1556315649471799, 993617155135620},
+ },
+ {
+ {5656453792030509, 6079591987914126, 5929179648294721, 5230798899043491, 3370342887971873},
+ {2735841961308013, 2116601197688202, 2652241807415589, 1945152844924315, 2885012584681659},
+ {551620533268687, 1182887684657061, 1043366705332762, 944140538303658, 2240921917214007},
+ },
+ {
+ {2427888929082724, 4467682652740956, 5335339067201761, 5550886290485514, 5050956980777821},
+ {2247945978763224, 215736457901546, 1047424049356243, 1389596126698944, 816935367913617},
+ {1146743855918524, 1418503734887175, 843342293437400, 1502230097098390, 1240491010654824},
+ },
+ {
+ {6701933119211633, 5059229274152685, 4982837924778640, 4159052306481152, 4290369756778959},
+ {2204538589507457, 3142843240983995, 2451576614290660, 3204217003708084, 2887474477188681},
+ {510455031824465, 465163402943305, 2022658124081289, 1881132727821470, 31746160856543},
+ },
+ {
+ {5097091659825113, 2826376647382075, 3998920599703675, 3513481695405562, 5076475699131519},
+ {1330330618013145, 2313004235002329, 3963525218487729, 2303930585911304, 2755772190474933},
+ {944243695677568, 255912283647788, 1855489019383837, 1244636060478392, 1911682985774639},
+ },
+ {
+ {5024454158738700, 2514912085825565, 3852574473189297, 4034915921452192, 3904120669219782},
+ {3843903221055742, 2416642267747155, 1715729591405051, 1735036083660438, 1182009761997504},
+ {1140604273028187, 1352033415206334, 1448886815181311, 941652546197192, 1001542060535421},
+ },
+ {
+ {4277058348919964, 5364603224614130, 5366326037527057, 4814184001945705, 5895346951506596},
+ {3602696745610322, 2198425366751348, 1768623515003979, 2456584282641319, 3022619356175890},
+ {1305849451281975, 726672899606505, 2105928429843370, 246834240873219, 1573506984361288},
+ },
+ },
+ {
+ {
+ {4821701574825479, 4751738035366345, 3733704008989173, 4812878081681692, 3510316573903125},
+ {427904865186293, 1703211129693455, 1585368107547509, 3688784302429584, 3012988348299225},
+ {1275068538599310, 513726919533379, 349926553492294, 688428871968420, 1702400196000666},
+ },
+ {
+ {3810616250567627, 4214696146321770, 5841309449432647, 3753213644462184, 4798035793202427},
+ {3313663849950481, 3213411074010628, 2573659446386085, 3297400443644764, 1985130202504037},
+ {818359826554971, 1862173000996177, 626821592884859, 573655738872376, 1749691246745455},
+ },
+ {
+ {4398313517418541, 5088388527765162, 4968565284650452, 4435773453041373, 4741970786827285},
+ {1988022651432119, 3333911312271288, 1834020786104820, 3706626690108935, 692929915223121},
+ {1129007025494441, 2197883144413266, 265142755578169, 971864464758890, 1983715884903702},
+ },
+ {
+ {4948148597287912, 3704086267538602, 4365531255192057, 2896988087581106, 5313917252680007},
+ {1291366624493056, 2633256531874362, 1711482489312443, 1815233647702022, 3144079596677715},
+ {2242724082797924, 1373354730327868, 1006520110883049, 2147330369940688, 1151816104883620},
+ },
+ {
+ {4667323107306775, 4619024517173644, 3407816205266473, 6398541848123859, 4222349233671575},
+ {3997520014069025, 4163522956860564, 2056329390702073, 2607026987995097, 3131032608056347},
+ {681981452362484, 267208874112496, 1374683991933094, 638600984916117, 646178654558546},
+ },
+ {
+ {2512483707152304, 5357659933447732, 5417239179350606, 4508304204210617, 2532054624493958},
+ {2265178468539480, 2358037120714814, 1944412051589650, 4093776581610705, 2482502633520820},
+ {715374893080287, 1173334812210491, 1806524662079626, 1894596008000979, 398905715033393},
+ },
+ {
+ {4348221360643351, 4174322814635610, 5293430650247335, 4930894772059273, 4824523600532224},
+ {2751826223412909, 3848231101880618, 1420380351989369, 3237011375206737, 392444930785632},
+ {1927770723575450, 1485792977512719, 1850996108474547, 551696031508956, 2126047405475647},
+ },
+ {
+ {2635705015322199, 3111746811317117, 5359223495008139, 3268925594263041, 3046050645563056},
+ {2112099158080129, 2994370617594963, 2258284371762679, 1951119898618915, 2344890196388664},
+ {77571826285752, 999304298101753, 487841111777762, 1038031143212339, 339066367948762},
+ },
+ {
+ {5619164208408509, 4079972709845361, 3927824185200012, 3681293890692042, 5452751544406703},
+ {2191882696778049, 531264700870777, 3039670365049278, 1359665656266722, 3162072763716517},
+ {1570940255668145, 688547574737286, 1632136413236589, 2053774689811525, 676669102580803},
+ },
+ {
+ {5183231995448322, 4155796849234556, 4791323788081582, 4471675968988079, 5711715782924180},
+ {3207409007530338, 935702897763596, 729948770061474, 1584905172662705, 2425339805308626},
+ {288239669792058, 2152796035840109, 162317061559789, 1257054119617939, 421141027109762},
+ },
+ {
+ {4958697699223355, 3221953471379609, 2818398572467973, 5875894486831009, 3850357049774603},
+ {642422906756119, 3171839279489789, 1695193497886789, 3040583315302385, 3362141503479163},
+ {1042979452017909, 1774768735282920, 464726722030945, 1465185933073826, 1382968477576580},
+ },
+ {
+ {3858506126065685, 4410239993278318, 3464562222229353, 3841799127123745, 3236074797259687},
+ {3342987691574741, 2002872538662690, 3240810091817983, 3479310152893167, 2490884376592639},
+ {2139337814897324, 178720275772072, 596052025976159, 666224594355251, 630639510547398},
+ },
+ {
+ {2744437082123657, 4441348097375482, 3869182720347428, 4304304367735980, 3086995265547722},
+ {2392789380667179, 812658446707360, 1599624958311986, 214741817968452, 1436587626236000},
+ {130387450082061, 1779587373012878, 417414670169839, 716150862374041, 154849814949784},
+ },
+ {
+ {4442837550688441, 4997631045842130, 5291735080737359, 4549950120656089, 4456650325708853},
+ {2746366883922045, 2305345226446032, 2885706560860073, 4092938150156125, 656228807731693},
+ {1456049106825164, 137394514200521, 2140871605490631, 1643256698410764, 679389221519059},
+ },
+ {
+ {3925184987729414, 3825370065750239, 2928329430708313, 5366989011209685, 4444246216420488},
+ {2346187442256272, 1014027377437197, 2069628555505675, 1559427210701775, 1456229816012936},
+ {2009324336353948, 1468073297564484, 1969534512584396, 827056802549955, 104599952309039},
+ },
+ },
+ {
+ {
+ {5505012288893163, 2599996010752544, 3918414180409193, 3140224808718007, 2832547501486604},
+ {2926794589205781, 2517835660016036, 826951213393477, 1405007746162285, 1781791018620876},
+ {1939560076207777, 1409892634407635, 552574736069277, 383854338280405, 190706709864139},
+ },
+ {
+ {5180561690600497, 4132075350834054, 4298520825287953, 5392062874453498, 5821901179394561},
+ {2177087163428741, 1439255351721944, 3459870654068041, 2230616362004768, 1396886392021913},
+ {1466980508178206, 617045217998949, 652303580573628, 757303753529064, 207583137376902},
+ },
+ {
+ {4105782219090338, 4130463869936394, 6031610648174487, 5523226095524059, 5632038039559529},
+ {3762856566592150, 2357202940576524, 2745234706458093, 1091943425335975, 1802717338077427},
+ {1963939888391106, 293456433791664, 697897559513649, 985882796904380, 796244541237972},
+ },
+ {
+ {3680158110175880, 5530714909790973, 4808440325428831, 4945009801397122, 4071158169963819},
+ {2668570812315008, 2641455366112301, 1314476859406755, 1749382513022778, 3413705412424739},
+ {204943430200135, 1554861433819175, 216426658514651, 264149070665950, 2047097371738319},
+ },
+ {
+ {5165635210954903, 4790335732463592, 5635372627881110, 5322093841581933, 4976543419424973},
+ {1934415182909015, 1393285083565062, 2768209145458208, 3409490548679139, 2372839480279515},
+ {665784778135882, 1893179629898606, 808313193813106, 276797254706413, 1563426179676396},
+ },
+ {
+ {4283233217201481, 4707596242598657, 4674086796207577, 5485113232161884, 3095373778602077},
+ {945205108984213, 2778077376644543, 1324180513733565, 1666970227868664, 2405347422974421},
+ {1476570093962618, 838514669399805, 1857930577281364, 2017007352225784, 317085545220047},
+ },
+ {
+ {3545343323078703, 4395424422887793, 5561961194168003, 4717696754764488, 3198688329157975},
+ {1461557121912823, 1600674043318359, 2157134900399597, 1670641601940616, 2379565397488531},
+ {357067959932916, 1290876214345711, 521245575443703, 1494975468601005, 800942377643885},
+ },
+ {
+ {5120856274973686, 3903907574784685, 4109012860330718, 3337396988900217, 3069232573515769},
+ {2817916472785262, 820247422481739, 994464017954148, 2578957425371613, 2344391131796991},
+ {771808161440705, 1323510426395069, 680497615846440, 851580615547985, 1320806384849017},
+ },
+ {
+ {6662756671601401, 5055771079546289, 4642910898897859, 4274227027260534, 5833718441044794},
+ {2335519494956627, 3820365010713627, 1944201046475949, 1640913863967574, 2358631279976586},
+ {990528501134234, 1330224017810407, 1573804236508381, 942270438439677, 25201841708767},
+ },
+ {
+ {5526427987749634, 4518401023168866, 4921120012283882, 4779318497665973, 4555652731610533},
+ {2646721458762538, 1247587116821480, 2586827199616378, 3932021497491885, 969339720975687},
+ {1595456591254808, 1919330451560855, 265402806641622, 1560117962587834, 1169927205192232},
+ },
+ {
+ {4189409997656536, 4659089518495636, 6000827340603279, 5702161301408170, 5941261317517041},
+ {3317917962903276, 1668664191271588, 1899844145838597, 1696011444672828, 2282054748309227},
+ {2126527989994119, 1465890683922518, 416427350021352, 1618807264846944, 1588324622180673},
+ },
+ {
+ {4009588676432813, 4225252562340771, 5138392626199289, 6147384375179966, 4323738229760897},
+ {2550824143198317, 3724772924079255, 2640826097206085, 2805004284285778, 3725892598967957},
+ {901870527597111, 1300831444709451, 1795706127510368, 1590464383227069, 60287918150860},
+ },
+ {
+ {4260735023331218, 2752239523202930, 4432983289513289, 6073621772440017, 5069964246448815},
+ {2411640257311042, 2404639281373100, 935718519552991, 2182928933394409, 3181304181386605},
+ {301088722784222, 902977224984285, 1485824849826196, 864674789855395, 2204280040105719},
+ },
+ {
+ {5294452585150653, 4378774784126084, 2684611835446325, 6054460125397337, 3113938028918105},
+ {1102630701890799, 2202327440719776, 1844385418066207, 1719220574774295, 3022438833862057},
+ {1192644591215061, 1951970263153038, 182489349589207, 1072483329544407, 1425993434915257},
+ },
+ {
+ {3759682407110969, 4757463391782573, 6126440026160055, 4699689556446215, 5715476431941391},
+ {2696424379059465, 2927324693839557, 2595575928464217, 3964369572567959, 2720628440266425},
+ {786193544150213, 816842401151828, 2071842707112420, 581055055128968, 310970557266803},
+ },
+ },
+ {
+ {
+ {3579768107573076, 3587300666628503, 3653386978219511, 5061736939322935, 6054960176639396},
+ {1219260086131896, 2898968820282063, 2331400938444953, 2161724213426747, 2656661710745446},
+ {417621685193956, 1429953819744454, 396157358457099, 1940470778873255, 214000046234152},
+ },
+ {
+ {3878872728667188, 4463402894965320, 4164169415301751, 3443570249906556, 4439109571211107},
+ {1268047918491954, 2172375426948536, 1533916099229249, 1761293575457130, 3842422480712013},
+ {1149147819689533, 378692712667677, 828475842424202, 2218619146419342, 70688125792186},
+ },
+ {
+ {4292523638342576, 4903155265245570, 5136143002823489, 3124449750693297, 5738994354400728},
+ {3551539230764990, 3690416477138006, 3788528892189659, 2053896748919837, 3260220846276494},
+ {2211311599327900, 2139787259888175, 938706616835350, 12609661139114, 2081897930719789},
+ },
+ {
+ {4097322728303089, 5725797875706037, 4654440700130628, 4178828883626228, 5693513031868506},
+ {1324994503390431, 2588782144267879, 1183998925654176, 3343454479598522, 2300527487656566},
+ {1079559557592645, 2215338383666441, 1903569501302605, 49033973033940, 305703433934152},
+ },
+ {
+ {3683815626821508, 4943964422665864, 3647446876506747, 4228674336449825, 5438052000093847},
+ {2346453219102138, 3637921163538246, 3313930291577009, 2288353761164521, 3085469462634093},
+ {1296625309219774, 2068273464883862, 1858621048097805, 1492281814208508, 2235868981918946},
+ },
+ {
+ {3534262737397977, 5245485311356750, 4279554456512807, 2770789343226274, 4078409823241192},
+ {1490330266465551, 1858795661361448, 3688040948655011, 2546373032584894, 3459939824714180},
+ {1525827120027511, 723686461809551, 1597702369236987, 244802101764964, 1502833890372311},
+ },
+ {
+ {6545268376680796, 4436205135889147, 3885200451296283, 4362482319222146, 6551744017455139},
+ {2365421849929742, 3485539881431101, 2925909765963743, 2114345180342964, 2418564326541511},
+ {503058759232932, 760293024620937, 2027152777219493, 666858468148475, 1539184379870952},
+ },
+ {
+ {2929839349119735, 5074186917559835, 3857102490299366, 4399562376560948, 3957863610776951},
+ {1916168475367211, 3167426246226591, 883217071712574, 363427871374304, 1976029821251593},
+ {1439489648586438, 2194580753290951, 832380563557396, 561521973970522, 584497280718389},
+ },
+ {
+ {4107979200870526, 4899400547785857, 5175087145170849, 5761419237914916, 2674185367684618},
+ {1133946710417756, 499737269360777, 1645961935513831, 2259932248870354, 2394185034627430},
+ {2211650710341615, 1916525167795392, 2219254718801699, 1123275886572725, 2065912631812720},
+ },
+ {
+ {2942743383283030, 4661681143781323, 4853180648224206, 3984362536169634, 3769046963947699},
+ {2547466619616960, 1599890997313053, 1767449403100900, 3146589914609346, 2442645855602917},
+ {1023269497317835, 1006858415503750, 2159836138753919, 1535892167365222, 826474553854585},
+ },
+ {
+ {4044410514205452, 4788613576788997, 4922881390894542, 4505428839963076, 3254381502973105},
+ {2881011303685958, 323260022642283, 2392511825935364, 2680218607241472, 2086628284323147},
+ {1011041096783712, 1570461284958064, 399516828994561, 1037957371973381, 293292885426852},
+ },
+ {
+ {3922699440356983, 4166667378343946, 4637678914861614, 4901406304713256, 5486018227566634},
+ {3894750463833161, 836931108663410, 4007195920412586, 1173057924841174, 2662523305285872},
+ {2047497366930440, 1249020434696646, 353399299276962, 1824831452522161, 1950016482901783},
+ },
+ {
+ {6367491312268994, 5392176809230541, 4683379383522741, 4425977262002237, 5566950871345983},
+ {2375227161224824, 2257267128164595, 1056955680380401, 2844088942852363, 1386644755985081},
+ {1251794829999036, 1772886866476173, 955066187540246, 1232293719330892, 396636503102089},
+ },
+ {
+ {5348918388440793, 5110360065015040, 4585673363095533, 4391593798666572, 4556880644633940},
+ {2531431177429893, 1987695830473810, 227622233346307, 1010967397553478, 1341018389661594},
+ {83039271672929, 423138535583767, 1183109031328467, 165324254826210, 1340545562288681},
+ },
+ {
+ {4651180052187971, 4721139042433965, 4397263424421690, 3818446426246947, 4163799598655846},
+ {1971810452973589, 1766684231420693, 299216980507446, 1405770006429853, 3505404036582454},
+ {814876839307346, 1973981610718707, 715190907115349, 1240128743335375, 100752655285750},
+ },
+ },
+ {
+ {
+ {5917065716904928, 4914443718136124, 5900862973774566, 4911826770493904, 3846361616833057},
+ {2439789269177838, 681223515948274, 1933493571072456, 1872921007304880, 2739962177820919},
+ {2102170800973153, 719462588665004, 1479649438510153, 1097529543970028, 1302363283777685},
+ },
+ {
+ {5650165172926835, 3913771113130458, 4910281332119388, 5068052063776583, 5612709493199633},
+ {3193865531532443, 3321113493038208, 2007341951411050, 2322773230131539, 1419433790163705},
+ {2214421081775077, 1165671861210569, 1890453018796184, 3556249878661, 442116172656317},
+ },
+ {
+ {5118771546583273, 6027449032225062, 3106360274232749, 4318897183975962, 4017125662271289},
+ {3005630360306059, 1666955059895018, 1530775289309243, 3371786842789394, 2164156153857579},
+ {1094538949313667, 1796592198908825, 870221004284388, 2025558921863561, 1699010892802384},
+ },
+ {
+ {3266123011223623, 3120950453625853, 6259609570067094, 3586752371060918, 6048545006453369},
+ {1951351290725195, 1916457206844795, 2449824998123274, 1909076887557594, 1938542290318919},
+ {764055910920305, 1603590757375439, 146805246592357, 1843313433854297, 954279890114939},
+ },
+ {
+ {4578096739917745, 5243693780562643, 3997054445402827, 5231313513873625, 3534834178102174},
+ {80113526615731, 764536758732259, 3306939158785481, 2721052465444637, 2869697326116762},
+ {525892105991110, 1723776830270342, 1476444848991936, 573789489857760, 133864092632978},
+ },
+ {
+ {4567722854714830, 3491727534333040, 3612522797131151, 4726210441025156, 4566029114558485},
+ {2794411533877810, 1986812262899320, 1162535242465837, 2733298779828712, 2796400347268869},
+ {1793193323953132, 91096687857833, 70945970938921, 2158587638946380, 1537042406482111},
+ },
+ {
+ {4644957907857340, 4595035516942998, 5590808199923137, 4081399466208167, 3445106834328894},
+ {1895854577604590, 3646695522634664, 1728548428495943, 3392664713925397, 2815445147288308},
+ {1611230858525381, 950720175540785, 499589887488610, 2001656988495019, 88977313255908},
+ },
+ {
+ {5377566504324214, 5594237977720934, 3960359138874383, 2924144408487157, 5824037597070734},
+ {3440880315164906, 2184348804772596, 3292618539427567, 2018318290311833, 1712060030915354},
+ {1508590048271766, 1131769479776094, 101550868699323, 428297785557897, 561791648661744},
+ },
+ {
+ {4856954879111275, 4243615896786977, 5034997993102829, 5162125577354786, 4490078142041683},
+ {432920540217177, 290770592514699, 627484756484379, 3076610223383366, 982836063036305},
+ {1857779135539838, 1774848070278290, 1383862392183037, 1948805685118077, 1143607656457264},
+ },
+ {
+ {5925968830616980, 5475584226682352, 5076614308992012, 5422447722241084, 4871259074999718},
+ {1741735203658460, 2040511596280954, 3245879940788742, 1750904751318660, 1289068422789788},
+ {103031326341235, 1843731695283489, 1066974994445109, 1210433521778964, 118970268237578},
+ },
+ {
+ {5029675928196841, 3837944199959690, 3856667351331398, 4299101000305422, 4340504849680591},
+ {1990983617046169, 3106460878930032, 1275461113767736, 1443049000516840, 1724142301140669},
+ {888262946735860, 1859763056800716, 714395964694532, 57820586821189, 354182478325612},
+ },
+ {
+ {3800325421725661, 5577357186452733, 3783169523012609, 5425955064608896, 6347571520159237},
+ {1658219197861187, 1494360717755939, 1921505970326949, 3049386312266838, 2475279382922093},
+ {1290766154788448, 1600589032610209, 784792370088015, 423204440383515, 459184860068298},
+ },
+ {
+ {3425205252763663, 5240056527358710, 4140356292677088, 4578393707504979, 5259386798582854},
+ {2215101089214073, 1997062079162084, 1249116849924618, 465107085276733, 1293244424458276},
+ {880894898454805, 639667973647762, 200272726605326, 297199521205209, 1640420309599773},
+ },
+ {
+ {4024399276644653, 4828207338948134, 4459991457755541, 6377452215012324, 4100282940590511},
+ {658635179203333, 3717891363165700, 3673816673290121, 2129566854376278, 1443087419989351},
+ {1532654097308642, 1958497386525981, 111717506991097, 1708848284574815, 1306115185198907},
+ },
+ {
+ {6112399743594082, 4482370964094274, 5295504988778619, 4900443159383520, 4202262340818045},
+ {2039429018914652, 3043146685732704, 1364716986897875, 1031303003048000, 1123429638631433},
+ {765045651502510, 451621180435426, 15885268584069, 767513226653014, 768056106241896},
+ },
+ },
+ {
+ {
+ {4032987623010691, 3949423965177593, 3633193504625235, 4678793759655164, 3734854480100484},
+ {3008217384184691, 2489682092917849, 2136263418594015, 1701968045454886, 2955512998822720},
+ {2175517777364616, 708781536456029, 955668231122942, 1967557500069555, 2021208005604118},
+ },
+ {
+ {3694962906564668, 2643675345331409, 4432646948339879, 4968138170389248, 3845898010522424},
+ {3366935780292116, 2476017186636029, 915967306279221, 593866251291540, 2813546907893254},
+ {850858855888869, 319436476624586, 327807784938441, 740785849558761, 17128415486016},
+ },
+ {
+ {3776976050663564, 5477805104091557, 2545236069347884, 4651869248468534, 4641561625804457},
+ {2132756334090048, 2788047633840893, 2300706964962114, 2860273011285942, 3513489358708031},
+ {1121075518299410, 2071745529082111, 1265567917414828, 1648196578317805, 496232102750820},
+ },
+ {
+ {5158525177930532, 3420610809262104, 2827455773116173, 5409358332231883, 5000374192034028},
+ {2374121042985030, 3274721891178932, 2001275453369483, 2017441881607947, 3245005694463250},
+ {1954109525779738, 2117022646152485, 338102630417180, 1194140505732026, 107881734943492},
+ },
+ {
+ {4610031103869799, 4566082599491057, 6017046282479905, 5310858379140016, 4504138118839608},
+ {1714785840001267, 4288299832366837, 1876380234251965, 2056717182974196, 1645855254384642},
+ {2002850762893643, 1243624520538135, 1486040410574605, 2184752338181213, 378495998083531},
+ },
+ {
+ {4119798625761979, 5219024680951196, 4543568213831910, 4424867828271409, 5157422279171799},
+ {922510868424903, 1089502620807680, 402544072617374, 1131446598479839, 1290278588136533},
+ {162892278589453, 182585796682149, 75093073137630, 497037941226502, 133871727117371},
+ },
+ {
+ {4201115364782060, 3320803158679711, 4190964847185163, 3800027019416103, 4185567469546654},
+ {4166396390264918, 1608999621851577, 1987629837704609, 1519655314857977, 1819193753409464},
+ {1730519386931635, 1393284965610134, 1597143735726030, 416032382447158, 1429665248828629},
+ },
+ {
+ {4551201741097278, 3774114323393256, 2689506075058172, 3065835144123274, 2587730464618792},
+ {360275475604546, 2799635544748326, 2467160717872776, 2848446553564254, 2584509464110332},
+ {1291597595523886, 1058020588994081, 402837842324045, 1363323695882781, 2105763393033193},
+ },
+ {
+ {5895867926878639, 6191714343966274, 3878657686711880, 3772412065246579, 5254560912358513},
+ {1828399243003455, 2730967851207580, 2809663501613790, 3291961475373747, 2085819249159773},
+ {1604304703501714, 1563946362290690, 2128875205288733, 257625874150601, 2149102916187814},
+ },
+ {
+ {5883573429799187, 4805272859062230, 2886195180819460, 4460210052098162, 3528150621150027},
+ {1960233741679201, 2996857902780426, 2245274121401778, 4454263006625692, 1110175461750907},
+ {1392548583294657, 697289852607029, 746483005053522, 734366559550160, 929768637070953},
+ },
+ {
+ {5047299589947009, 4992620901798841, 5716112978503343, 3741839332315327, 4983937719789158},
+ {1673816614349955, 3255360796858239, 2753984593405885, 2969035246796379, 2420194805583742},
+ {1159863250954626, 1438000622355742, 254045494246044, 1734996482788294, 484539502358623},
+ },
+ {
+ {3740619537304301, 4538691700403019, 5325131682689719, 4744914552382795, 3720848390661317},
+ {1212935253295623, 2026300849238541, 3447883684227245, 1364910689032303, 3019520894163467},
+ {2014517785153097, 1607430272140319, 1855018731367383, 2200629261829065, 987339037980209},
+ },
+ {
+ {4426735416351775, 4348191232564971, 5508438055207952, 2420023948055060, 6131298111765032},
+ {2763109171958591, 4020627496535071, 3147539030064750, 2177710318971894, 2463269685396658},
+ {831460863845953, 1946524324541207, 761958653274011, 1366775091595921, 1187427455457947},
+ },
+ {
+ {3125773853625002, 4814913241945202, 4262512130702308, 3321059176595839, 3567623941809388},
+ {2822285257464218, 607639870769094, 2857291392676774, 2362021242026611, 3328398883102618},
+ {1972329598509655, 34473001166350, 1728817301333588, 1539479676009467, 1694458836743324},
+ },
+ {
+ {4805304108915754, 5125985383393506, 5019883131944028, 4580919291870093, 4156575634700942},
+ {1575955157633628, 3067048601687650, 2501496271474334, 4193474980184415, 3288209175931426},
+ {1442686188453203, 1751694580158105, 824989332883473, 614995267948452, 1497907423783166},
+ },
+ },
+ {
+ {
+ {4408790844622027, 4479344310838572, 4120849908116869, 3006675674164362, 4006042157952305},
+ {2361321796251793, 3967057562270386, 1112231216891515, 2046641005101484, 2386048970842261},
+ {1846089562873800, 98894784984326, 1412430299204844, 171351226625762, 1100604760929008},
+ },
+ {
+ {5371908961903233, 6206610140112367, 4204489822423303, 4507924897296559, 4322883368647362},
+ {2335972195815721, 2751510784385293, 425749630620777, 1762872794206857, 2864642415813208},
+ {523094549451158, 401938899487815, 1407690589076010, 2022387426254453, 158660516411257},
+ },
+ {
+ {3975648787468681, 4460622334219928, 3970548136462187, 4226068267807189, 3446012315943388},
+ {612867287630009, 2700012425789062, 2823428891104443, 1466796750919375, 1728478129663858},
+ {1254114807944608, 977770684047110, 2010756238954993, 1783628927194099, 1525962994408256},
+ },
+ {
+ {5270938303411141, 3005889362003651, 3774991859324322, 4939345652492557, 5016292135810879},
+ {2484263871921055, 1948628555342433, 1835348780427694, 1031609499437291, 2316271920603621},
+ {1255955808701983, 1700487367990941, 1166401238800299, 1175121994891534, 1190934801395380},
+ },
+ {
+ {5381119574505877, 4424637839817897, 4775904018594624, 3906943141245230, 5389829033800309},
+ {2600943821853521, 1337012557669161, 1475912332999108, 3573418268585706, 2299411105589567},
+ {375806028254706, 214463229793940, 572906353144089, 572168269875638, 697556386112979},
+ },
+ {
+ {4199915895763317, 4306698118173043, 4456738998669147, 4714126432522633, 3038393400292872},
+ {1168827102357825, 823864273033637, 4323338565789945, 788062026895923, 2851378154428610},
+ {1915320147894736, 156481169009469, 655050471180417, 592917090415421, 2165897438660879},
+ },
+ {
+ {3081796668531198, 4720661405375633, 3938365723488886, 5850548444590341, 6227423178100675},
+ {1726336468579724, 1119932070398949, 1929199510967666, 2285718602008207, 1836837863503149},
+ {384301494966394, 687038900403062, 2211195391021739, 254684538421383, 1245698430589680},
+ },
+ {
+ {3700877198419411, 4541885072828491, 4388337472863078, 4398292814526820, 5228760778493620},
+ {1247567493562669, 4229981908141095, 2435671288478202, 806570235643434, 2540261331753164},
+ {1201928866368855, 800415690605445, 1703146756828343, 997278587541744, 1858284414104014},
+ },
+ {
+ {3752846457602541, 6051774917153047, 3492614771149749, 5278195549012933, 3851678670548516},
+ {1251637423994861, 2037585266091733, 1171182249847439, 1503770304884899, 1938920423810268},
+ {2232651154426557, 514116965743385, 983369998596377, 1516132019440103, 1692302360068816},
+ },
+ {
+ {4860689994687041, 4138464101331517, 4969836424606600, 3370757908330089, 3017690336853320},
+ {3753543276036939, 3037198013841237, 3063121586956950, 2967087171212783, 2388800428725970},
+ {1485716675407214, 1159619625081800, 197549418633523, 776030397384998, 252064880140599},
+ },
+ {
+ {4116450327020509, 4602447751059104, 4624188822504437, 3786392386215792, 4018069243702311},
+ {3871066258534097, 182982139320960, 3846997414183091, 1246347657803786, 966334158538299},
+ {2049526525941781, 1431983169228179, 3669291297222, 769041933664973, 1760968694339914},
+ },
+ {
+ {5411552533375856, 4680723354107633, 5764453140711672, 3663956673248104, 5834177820168369},
+ {2029548972200054, 541413050113871, 2564963424993232, 3150712544977872, 2699322542672271},
+ {513500031822581, 836561902873502, 82127696349010, 1591221763097659, 725989684331322},
+ },
+ {
+ {4424236584915172, 3098952863411429, 2785705377786181, 4107549518995786, 5362683219257666},
+ {1071376590195254, 1910139340535847, 1936705400579295, 3523841068963764, 2356086500199738},
+ {357287898232758, 1026512116626804, 1875958986125314, 1743551742697910, 1876232951311596},
+ },
+ {
+ {4332669232306147, 5882550009365637, 3881970305785489, 6570990168178499, 3489314838073396},
+ {294975596735049, 2145292931466411, 3320625656613141, 2284954433570209, 3090254877821144},
+ {1234852195927098, 3815763342761, 2085449281682153, 516098044852331, 164426832090235},
+ },
+ {
+ {3292223948318582, 4463121371440286, 5163264330075513, 4550237542693388, 4544934760614835},
+ {2590122580645644, 1011386629068498, 960875975353535, 3791419723576010, 2273772136048635},
+ {1749858954947675, 1561651915395372, 1738700200168191, 397865176422134, 1467025336447738},
+ },
+ },
+ {
+ {
+ {3011428551915689, 3264493287961099, 4857379860456993, 4749679688758046, 4282178671364408},
+ {2608268623334125, 3034173730618399, 1718002439402869, 3644022065904502, 663171266061950},
+ {2040672435071076, 888593182036908, 1298443657189359, 1804780278521327, 354070726137060},
+ },
+ {
+ {4711536788361604, 4516566538409613, 5324597415653586, 3262240285890532, 3953172703826057},
+ {1894938527423184, 3715012855162525, 2726210319182898, 2499094776718546, 877975941029127},
+ {218882774543183, 533427444716285, 1233243976733245, 435054256891319, 1509568989549904},
+ },
+ {
+ {4802737216830789, 3846171402668813, 5371658121409568, 4761371218007175, 4056812806828167},
+ {4140638349397055, 3303977572025869, 3465353617009382, 2420981822812579, 2715174081801119},
+ {1806842755664364, 2098896946025095, 1356630998422878, 1458279806348064, 347755825962072},
+ },
+ {
+ {5169106331623846, 4777370102540357, 5302836601573124, 5351928617448052, 4063248596493177},
+ {1402334161391744, 3811883484731547, 1008585416617746, 1147797150908892, 1420416683642459},
+ {1468412523962641, 771866649897997, 1931766110147832, 799561180078482, 524837559150077},
+ },
+ {
+ {5770203524895319, 4659978036228594, 3527448837914025, 4951338033258915, 4756786089433589},
+ {2223212657821831, 2882216061048914, 2144451165500327, 3068710944633039, 3276150872095279},
+ {2022215964509735, 136144366993649, 1800716593296582, 1193970603800203, 871675847064218},
+ },
+ {
+ {5731767721917939, 4837733510733388, 5091167195790575, 4937212217651675, 5106990027743699},
+ {1862751661970309, 851596246739884, 1519315554814041, 3794598280232697, 3669775149586767},
+ {121893973206505, 1843345804916664, 1703118377384911, 497810164760654, 101150811654673},
+ },
+ {
+ {2836122124869624, 4884260866172613, 4618439021898554, 2906882084185319, 4363655839720099},
+ {2710146069631716, 2542709749304591, 1452768413850678, 2802722688939463, 1537286854336537},
+ {996965581008991, 2148998626477022, 1012273164934654, 1073876063914522, 1688031788934939},
+ },
+ {
+ {3949497701489527, 5838943331198768, 5334888242577534, 5453016312620545, 4792359904762516},
+ {3175286832534829, 2085106799623354, 2779882615305384, 1606206360876187, 2987706905397772},
+ {1419122478109648, 1325574567803701, 602393874111094, 2107893372601700, 1314159682671307},
+ },
+ {
+ {4954618339278337, 3422305785425208, 4565328836139485, 3192891441493866, 4836379953614308},
+ {855396458506247, 2470294140783466, 4436061492213979, 1754097632720488, 4112391040574456},
+ {985511568884890, 583904209238998, 516128993365349, 1235577837475387, 1449904660690748},
+ },
+ {
+ {5895940682517746, 4393238442290827, 4244687834629046, 5245476345580864, 4795864303032094},
+ {1477173810966796, 3207978347793495, 2656860913951054, 825157489520718, 2782873637674750},
+ {12931323257125, 562700432679180, 780577595442459, 440747171628074, 31993258894121},
+ },
+ {
+ {5231235667053925, 5090675513104692, 4933657013889560, 5325938777525481, 4583903281916140},
+ {2159229926833831, 1114556221271056, 2050697214928106, 2553796628978461, 2874553280901592},
+ {1487427059839672, 1966052937474419, 398866894053509, 2040723626090668, 1223074007342359},
+ },
+ {
+ {3294796902098517, 3902877656361122, 4227499257540629, 5627711142390550, 5038311124292534},
+ {2677874505039557, 678833394869758, 3687464289589147, 1992670845292812, 654778477108270},
+ {651854196246431, 2602668557028, 1822678077647200, 2072267608435533, 435243653222236},
+ },
+ {
+ {4313218743534013, 3972172746637215, 5399714135650344, 5547659251980199, 4837224811093838},
+ {2487053592812311, 2315738098787275, 1210583464083714, 1056644723032111, 781277197910636},
+ {864616322745343, 1362699579128647, 1361407419724038, 495664202671974, 662016549521786},
+ },
+ {
+ {6154029469581357, 5498138279894180, 3281752713530018, 3501917375982713, 4910547940594210},
+ {2672416110637939, 3245298985644332, 1344078619347414, 2037703067415133, 2697812769645364},
+ {325041473989085, 842410640177049, 1052993540865892, 2093280369201601, 361408260911216},
+ },
+ {
+ {4388597398802075, 4997551911436129, 2851157853262017, 4795345418726848, 4139150667184165},
+ {1519253497716003, 3826826078266703, 2262276529333275, 1386373334348474, 3240242941348023},
+ {763973845167102, 1151501355459051, 1283654593302800, 584312404348728, 1219116745359281},
+ },
+ },
+ {
+ {
+ {5676939182921069, 5322204711648077, 4551121131734783, 5427708347935459, 5239023033125000},
+ {2201150872731785, 2180241023425241, 2349463270108411, 1633405770247823, 3100744856129234},
+ {830104860549448, 1886653193241086, 1600929509383773, 1475051275443631, 286679780900937},
+ },
+ {
+ {4781988283280724, 4990742996470332, 5431361832879221, 4684617167544704, 3868686514426533},
+ {3828911108518224, 3282698983453994, 2396700729978777, 4216472406664814, 2820189914640497},
+ {1191033906638969, 940823957346562, 1606870843663445, 861684761499847, 658674867251089},
+ },
+ {
+ {5126469419668815, 4155719092635613, 4174388435346876, 3772374525285681, 5590700387545135},
+ {1875032594195527, 1427106132796197, 2976536204647406, 3153660325729987, 2887068310954007},
+ {25465949416618, 1693639527318811, 1526153382657203, 125943137857169, 145276964043999},
+ },
+ {
+ {4258045666458167, 5238362362206654, 4758242557133921, 3658013106441212, 2491103563202933},
+ {2466539671654587, 920212862967914, 4191701364657517, 3463662605460468, 2336897329405367},
+ {1619678837192149, 1919424032779215, 1357391272956794, 1525634040073113, 1310226789796241},
+ },
+ {
+ {4248523125120879, 4096142580252307, 5489055327836539, 3417724495086206, 4815108317240624},
+ {3292563523447371, 1704449869235351, 2857062884141577, 1998838089036354, 1312142911487502},
+ {43173156290518, 2202883069785309, 1137787467085917, 1733636061944606, 1394992037553852},
+ },
+ {
+ {4449014387058033, 5297853724611810, 5533789687884231, 2519432329227148, 4292277862887871},
+ {670078326344559, 2807454838744604, 2723759199967685, 2141455487356408, 849015953823125},
+ {1812516004670529, 1609256702920783, 1706897079364493, 258549904773295, 996051247540686},
+ },
+ {
+ {5827060326775227, 5766290385251485, 3123576947163146, 5563678522359472, 3964036703348132},
+ {1540374301420565, 1764656898914615, 1810104162020396, 3175608592848336, 2916189887881826},
+ {1696163952057966, 1391710137550823, 608793846867416, 1034391509472039, 1780770894075012},
+ },
+ {
+ {5101135942842208, 4543974686113080, 4194056217641295, 5689084272866427, 2564466095709391},
+ {1367603834210822, 4383788460268472, 890353773628143, 1908908219165595, 2522636708938139},
+ {1919411405316294, 1234508526402192, 1066863051997083, 1008444703737597, 1348810787701552},
+ },
+ {
+ {4132340278436948, 4005982088010057, 3308609415246807, 3692550296463618, 3956871570338410},
+ {1096972188133236, 3816049499915451, 1251976741328773, 1219603529073670, 1078899265206338},
+ {950202511700693, 1240039391743494, 1169033682725545, 1423696267961315, 86935143579550},
+ },
+ {
+ {4756214981813576, 5522632333569959, 3862983342357100, 4309495274365548, 5713360895956932},
+ {2683363149107878, 1470385524874179, 725539084456484, 3271790833618750, 1222340934084308},
+ {200587706310533, 896271240996831, 1147839003219597, 673448965331479, 548900916085084},
+ },
+ {
+ {3550032568832337, 4838968015489313, 4675889877479625, 3212531632461645, 4765584451232964},
+ {1405860849520605, 738725235942165, 399531320766275, 3195580921007755, 1958618144816834},
+ {94349687650983, 306368484955948, 1759034073892087, 2030110332880331, 1270749214795711},
+ },
+ {
+ {2967631947537871, 4383349957254579, 3922288445505558, 5226885511958431, 3995794596785200},
+ {1753118377928377, 3368465588051047, 1755914948419738, 3441455854862245, 647766692547292},
+ {2005162920381704, 1507493192705080, 1430523618875617, 131673490468702, 662093487452573},
+ },
+ {
+ {2747463689102953, 5007357876041009, 5072033195962826, 4670246809435049, 5673751346141763},
+ {2718321167227969, 855141819034537, 1769780985173952, 3439183400564947, 1192259870209089},
+ {747964066233340, 2037427400347459, 49693847757217, 2003202980691532, 2230561945728266},
+ },
+ {
+ {4747984612298188, 4723422270130357, 4628272886928943, 3839214906514725, 5200339299152060},
+ {1424576382204282, 350051250024461, 3895326653518337, 3070821812734749, 3346444741017048},
+ {2021002858021100, 839958875652478, 2080082610761570, 1282995787185392, 313106058533657},
+ },
+ {
+ {5293324356940491, 3886891387640488, 5386021427475165, 4491415749098830, 3988924707585306},
+ {2136145829133251, 713070507515938, 1951333115623761, 3770252317439440, 1824831508473442},
+ {2203533335083089, 2130417962449796, 217179607020589, 153498131255469, 1884913426826060},
+ },
+ },
+ {
+ {
+ {6357530995067419, 4511707601241201, 4853814131499793, 3027006748267833, 4004117462852039},
+ {2102881477513865, 3822074379630609, 1573617900503707, 2270462449417831, 2232324307922097},
+ {1417148368003523, 721357181628282, 505725498207811, 373232277872983, 261634707184480},
+ },
+ {
+ {3519916180986434, 5063756715513304, 5306226466970938, 4461989750290959, 5633593412950483},
+ {2186733281493248, 2250694917008620, 1014829812957440, 2731797975137637, 2335366007561721},
+ {615183387352312, 917611676109240, 878893615973325, 978940963313282, 938686890583575},
+ },
+ {
+ {4051478965894094, 5415732403270882, 4529567395411473, 4935730075960955, 4778168617632490},
+ {522024729211672, 3296859129001056, 1892245413707789, 1907891107684253, 2059998109500714},
+ {98698809797682, 2144627600856209, 1907959298569602, 811491302610148, 1262481774981493},
+ },
+ {
+ {5721409450692386, 4425747098618406, 6490527463642820, 3639914744810785, 4516285758530664},
+ {1791451399743152, 1713538728337276, 2370149810942738, 1882306388849953, 158235232210248},
+ {1650875518872272, 1136263858253897, 1732115601395988, 734312880662190, 1252904681142109},
+ },
+ {
+ {5306746809205765, 3120741251682392, 2568099116674910, 5447095217001045, 2823024101589818},
+ {2624786269799113, 2777230729143418, 2116279931702134, 2753222527273063, 1907002872974924},
+ {227742695588364, 1776969298667369, 628602552821802, 457210915378118, 2041906378111140},
+ },
+ {
+ {3832015885289562, 4129797318027691, 5360746788631408, 5207122354148972, 4434563787896849},
+ {815000523470260, 3164885502413555, 3303859931956420, 1345536665214222, 541623413135555},
+ {1870080310923419, 71988220958492, 1783225432016732, 615915287105016, 1035570475990230},
+ },
+ {
+ {4881216209018060, 3833780216763759, 5307643745501116, 4286182636729437, 5147443675842680},
+ {2982787564515398, 857613889540279, 1083813157271766, 1002817255970169, 1719228484436074},
+ {176957326463017, 1573744060478586, 528642225008045, 1816109618372371, 1515140189765006},
+ },
+ {
+ {2695191990687280, 4737393024215632, 4451306435997662, 3263658520201184, 3226476650748376},
+ {1888911448245718, 3638910709296328, 4176303607751676, 1731539523700948, 2230378382645454},
+ {1846351103143623, 1949984838808427, 671247021915253, 1946756846184401, 1929296930380217},
+ },
+ {
+ {4257691815043557, 4587099125055339, 4378829326829150, 4530783676112038, 5088169500723328},
+ {2633154847819111, 2373317802678415, 4226812651282694, 3531985668346704, 3254298087102270},
+ {1896123626988797, 1131351092678624, 1831358114864483, 1263257519094555, 153161823153575},
+ },
+ {
+ {5013999188326350, 5342051120597129, 5658875547575315, 4993589587822012, 3418484323529615},
+ {2875848054604140, 2609079967536269, 3221396114275243, 1330649045956928, 1828925625187427},
+ {85523512650066, 1145743424577874, 270900922559567, 1781500837265517, 1998986005265292},
+ },
+ {
+ {4300315009401728, 4620112123771453, 2612760971016545, 3052063778972094, 4706549333122035},
+ {2904227921845290, 4267364811643403, 1994336236107343, 2172724361186958, 2854607055726693},
+ {2127639189718319, 2205729457048157, 1849555339256920, 1751645797856968, 1883138982486949},
+ },
+ {
+ {3989916020510698, 4741941595447558, 5214589701377240, 4351148330446081, 3428672470823222},
+ {762600272699964, 2753498328779892, 3316416370655704, 526788695246361, 3062867170941268},
+ {1503368613839734, 2009362771486879, 495897391474535, 1905468005297555, 272387388531978},
+ },
+ {
+ {5813046901089551, 5050432868964283, 4705275668110217, 4196337029208819, 5257156494192722},
+ {1830890930331365, 3828112268992685, 3895633691902557, 3356965264729727, 2386741853982022},
+ {995710478389517, 1430833880042694, 1172677663947400, 1545257382741759, 1798260148494462},
+ },
+ {
+ {5205850356707429, 4686811868434220, 5616916192509070, 4494846080958018, 5419646380822597},
+ {1276458355120913, 2527187906858810, 1130163473530636, 3533175711581762, 2161750040536619},
+ {1025062667466023, 43711902086443, 2210112172846377, 233136450830559, 1412931651896051},
+ },
+ {
+ {3560341629038503, 4545538003102686, 5283269045082286, 4816839347899222, 4801547130939062},
+ {2448047678851139, 599053419172738, 3080495073729726, 1198848441856844, 1359787207816262},
+ {555971766815523, 2160228751293088, 266579216919501, 408880354152864, 2184471346102790},
+ },
+ },
+ {
+ {
+ {5195617294728737, 5226905206197221, 3889841953548511, 5251818933360801, 4838188827894395},
+ {849646212451983, 1410198775302919, 2325567699868943, 1641663456615811, 3014056086137659},
+ {22893968530686, 2235758574399251, 1661465835630252, 925707319443452, 1203475116966621},
+ },
+ {
+ {3154905071699595, 4930741522303542, 5064786644540271, 4136130058087200, 4165945522107466},
+ {3053098849470395, 3985092410411378, 1664508947088595, 2719548934677170, 3899298398220870},
+ {1344191060517578, 1960935031767890, 1518838929955259, 1781502350597190, 1564784025565682},
+ },
+ {
+ {4168985401048642, 5601942199123232, 4509535428414908, 4252327476037085, 6042239923552064},
+ {2925523165433334, 1979969272514922, 3427087126180756, 1187589090978665, 1881897672213940},
+ {2495540013192, 678856913479236, 224998292422872, 219635787698590, 1972465269000940},
+ },
+ {
+ {4698182657338567, 5017916408838259, 3081477769920918, 3928215500558329, 5313704211766335},
+ {271413961212179, 3604851875156899, 2596511104968730, 2014925838520661, 2006221033113941},
+ {1980510813313589, 1948645276483975, 152063780665900, 129968026417582, 256984195613935},
+ },
+ {
+ {5300264442994823, 3794960652558197, 6004497419208260, 6170915605358895, 5102903504401205},
+ {1860190562533083, 1936576191345085, 2712900106391212, 1811043097042829, 3209286562992083},
+ {1151480509533204, 2136010406720455, 738796060240027, 319298003765044, 1150614464349587},
+ },
+ {
+ {5520821677598445, 4505587343518853, 4486119403320947, 5124882310463887, 4384352945448272},
+ {1731069268103131, 2987442261301335, 1364750481334267, 2669032653668119, 3178908082812908},
+ {1567828528453324, 1017807205202360, 565295260895298, 829541698429100, 307243822276582},
+ },
+ {
+ {4341766796632437, 4105940157601428, 4403780572905254, 4391581105946996, 4661670073235412},
+ {249079270936229, 1501514259790706, 3199709537890096, 944551802437486, 2804458577667728},
+ {1338766321464554, 1906702607371284, 1519569445519894, 115384726262267, 1393058953390992},
+ },
+ {
+ {4136644411018817, 5105079697639574, 5123803130450031, 3331327213803161, 3453876506817262},
+ {3616421371950629, 3764188048593604, 1926731583198685, 2041482526432505, 3172200936019022},
+ {840922919763324, 727955812569642, 1303406629750194, 522898432152867, 294161410441865},
+ },
+ {
+ {5565570118069330, 4591619629413879, 3505524267391659, 5911065393515679, 5626780252302286},
+ {2954349327665336, 2875421537282295, 1177907047549607, 2315244756624323, 3303388475971642},
+ {1193532613439179, 1341357357703238, 1857522674746129, 587336359047056, 1462817734082691},
+ },
+ {
+ {5032608083579310, 5556680383291862, 4639031978972564, 2550751933150061, 4661900946642239},
+ {981709001326388, 2228829982452486, 1195252744174570, 1961335123791201, 473922585791741},
+ {158547452916311, 1806851940249257, 1888549274109445, 1234535032385844, 755999937979748},
+ },
+ {
+ {5099505633219587, 3654947652195304, 4632839805758299, 3516983533390311, 3156502843280841},
+ {2235936902666817, 1844821659342916, 4255944160143733, 2705728103151199, 1360010073190141},
+ {1966276380904262, 1243659846916250, 1230287549611464, 1790496592504769, 385075881855087},
+ },
+ {
+ {5102974111125320, 5352605641984611, 4254853167292498, 4166876022626639, 4692858050734664},
+ {808958715657412, 2787760179369277, 2812754371047796, 3109195163271007, 3174221799565416},
+ {1970356456788069, 1887106101566224, 2120741856788965, 1887465058487327, 166078852378175},
+ },
+ {
+ {5268074145727905, 3102961204581063, 5775739741243707, 6623549226998551, 5355512520264473},
+ {1475882426726637, 2923995069592105, 2595116660588037, 2134573872614909, 2857982748479313},
+ {957649428811476, 1521919451665798, 1487878569331559, 1715152263604455, 2000934618350472},
+ },
+ {
+ {3462276468747197, 4403243110229213, 5274708467449337, 4946143993185919, 6100123938510411},
+ {2624197675552195, 2160845895419703, 991891416996825, 2705836223851003, 2307139020684469},
+ {231885416467149, 648441606302746, 1371491506634443, 193373311482025, 2106953050161716},
+ },
+ {
+ {2408565470230034, 4633147941257550, 4425551739809483, 4183865634168848, 4784444305258783},
+ {2307403528152576, 3136574081495182, 3694424861021853, 1950918571001278, 1747697954472435},
+ {931185174846608, 872635055344100, 1155298897916392, 1344438153479985, 863698029056587},
+ },
+ },
+ {
+ {
+ {2611656183523465, 4684513982859178, 5365326100017121, 4722407564633480, 2827426586917747},
+ {2605560604520539, 1598361541848742, 3374705511887547, 4174333403844152, 2670907514351827},
+ {755467689082474, 909202735047934, 730078068932500, 936309075711518, 2007798262842972},
+ },
+ {
+ {3236138991462016, 3067527600191131, 3896954399398994, 3910874778063800, 3938401465669403},
+ {1609384177904054, 2614544999293875, 1335318541768200, 3052765584121496, 2799677792952659},
+ {1697863093781930, 599794399429786, 1104556219769607, 830560774794755, 12812858601017},
+ },
+ {
+ {4108730476499120, 5181690479373092, 4171978954440413, 3511327647445115, 4559140599266006},
+ {1168737550514982, 897832437380552, 463140296333799, 2554364413707795, 2008360505135500},
+ {1158643631044921, 476554103621892, 178447851439725, 1305025542653569, 103433927680625},
+ },
+ {
+ {3077203098880308, 4396008401246031, 4177351818329890, 6418777467377480, 5519551756318358},
+ {2176793111709008, 3828525530035639, 2009350167273522, 2012390194631546, 2125297410909580},
+ {1807108316634472, 1534392066433717, 347342975407218, 1153820745616376, 7375003497471},
+ },
+ {
+ {4732167545780233, 5368693586150714, 2609883700135802, 4663217517029815, 3612437739977844},
+ {3234860815484973, 2683011703586488, 2201903782961092, 3069193724749589, 2214616493042166},
+ {234147501399755, 2229469128637390, 2175289352258889, 1397401514549353, 1885288963089922},
+ },
+ {
+ {5617390325210756, 5554766767336738, 5549530285921438, 6514965868913137, 3937966638306001},
+ {3363562226636810, 2504649386192636, 3300514047508588, 2397910909286693, 1237505378776769},
+ {1054097349305049, 1872495070333352, 182121071220717, 1064378906787311, 100273572924182},
+ },
+ {
+ {4607833422014698, 3800719604873494, 4476341726952553, 4306709190801725, 3295603202700400},
+ {3558210666856834, 1627717417672446, 2302783034773665, 1109249951172249, 3122001602766640},
+ {216762189468802, 707284285441622, 190678557969733, 973969342604308, 1403009538434867},
+ },
+ {
+ {4847405480488793, 3554016671099447, 2818672356908788, 4302938753224251, 4825028485754775},
+ {3530824104723725, 2596576648903557, 2525521909702446, 4086000250496689, 634517197663803},
+ {470067171324852, 1618629234173951, 2000092177515639, 7307679772789, 1117521120249968},
+ },
+ {
+ {4032307292940140, 4855742012511787, 4007061004220393, 4186026976205829, 5188147460015837},
+ {1726290253928048, 2108179153379055, 3599306339052623, 3804322907336713, 740669388116407},
+ {1893601910775915, 1893561171028788, 174914675480509, 2073460144115735, 250678301747773},
+ },
+ {
+ {5696478198308385, 3135077959467853, 5039986204304988, 5696739636381970, 5163380137461980},
+ {1473356281060031, 1850501243620073, 559809451272168, 2164039335364390, 2799937740729438},
+ {506406583155327, 1903499899096002, 445887262445598, 866962765497367, 55809365421254},
+ },
+ {
+ {5290224396694939, 4705669579710662, 4614921349557141, 5027610124814334, 5088773866023979},
+ {2009707214072007, 3490160897828618, 275706542492147, 1283471147003836, 2026672645131195},
+ {1123457689056584, 2213608670005209, 1379370540202855, 2074314852377531, 864461310144552},
+ },
+ {
+ {5111150460891680, 4275734012505621, 4206718452855061, 3888755110807716, 5005016151412877},
+ {2967787444233740, 1413004988964951, 690605351712577, 3813861694171786, 728516486273669},
+ {2016155040846069, 1480238949730910, 882386999623863, 1367342654128568, 589184047321896},
+ },
+ {
+ {3850772783035735, 4143292076634522, 5556861502206409, 4279143658707597, 3550043180479289},
+ {3493927566017921, 3571431901909570, 2627286406743953, 2047641118374561, 1730233493072697},
+ {272317805124786, 1812925138663726, 1217316351219782, 1182300795957412, 1252963393607199},
+ },
+ {
+ {5371799854215572, 3393967588858477, 5067027508227680, 3852577519740789, 4734905175716170},
+ {3515527020405104, 2159318542704715, 1058260913419646, 2981918447395233, 1340478002453928},
+ {896362445577855, 1547885531466434, 942263962614365, 1148475609702329, 2122889133222112},
+ },
+ {
+ {5312477093520487, 3952229351525915, 5253212242457428, 4756871683292235, 4134773488559657},
+ {2735014629385533, 1581591485505255, 1720528958990566, 4161950575359359, 2332085424554487},
+ {704970088806441, 1168889861388831, 354811087636935, 1536113135588939, 2212112893107236},
+ },
+ },
+ {
+ {
+ {2828809211088312, 6295039889156786, 4429443549656884, 4678145777282455, 5916104705152820},
+ {2529951391976704, 1810282338562946, 1771599529530998, 3635459223356879, 2937173228157088},
+ {893719721537457, 1201282458018197, 1522349501711173, 58011597740583, 1130406465887139},
+ },
+ {
+ {4766083398225008, 5494110682478710, 2778685366456944, 2823464210331405, 4857685817649218},
+ {412607348255434, 1280455764199780, 2233277987330768, 2265979894086913, 2583384512102412},
+ {1820352417585487, 24495617171480, 1547899057533253, 10041836186225, 480457105094042},
+ },
+ {
+ {5647768329980203, 5108044017780681, 3796340935441384, 4177115363811274, 5130001056264497},
+ {2023310314989233, 2889705151211129, 2106474638900686, 2809620524769320, 1687858215057825},
+ {1922168257351784, 2018674099908659, 1776454117494445, 956539191509034, 36031129147635},
+ },
+ {
+ {4561842048916374, 4287612509327089, 4370291679808170, 5695284091186768, 4550521144824593},
+ {2796444352433270, 1039872944430373, 3128550222815858, 2962457525011798, 3468752501170219},
+ {272268252444639, 1374166457774292, 2230115177009552, 1053149803909880, 1354288411641016},
+ },
+ {
+ {5697036697171416, 5404706777075284, 5503272547981905, 4981184452172701, 4867839206068339},
+ {1857910905368338, 1754729879288912, 3137745277795125, 1516096106802165, 1602902393369811},
+ {886299989548838, 1538292895758047, 1590564179491896, 1944527126709657, 837344427345298},
+ },
+ {
+ {3561647617580592, 3713951676498321, 4714970494042065, 3796394966388927, 5531291426324585},
+ {3006358179063534, 1712186480903617, 3955456640022779, 3002110732175033, 2770795853936147},
+ {803217563745370, 1884799722343599, 1357706345069218, 2244955901722095, 730869460037413},
+ },
+ {
+ {5199950995983500, 5997984878609744, 5241636760987426, 5139985135222038, 5431082849981900},
+ {2941099284981214, 1831210565161070, 3626987155270686, 3358084791231418, 1893781834054268},
+ {1949114198209333, 1104419699537997, 783495707664463, 1747473107602770, 2002634765788641},
+ },
+ {
+ {3320700462489453, 4258691810757797, 5637648896716044, 3890560459865337, 4307195898311025},
+ {1607325776830197, 2782683755100581, 1451089452727894, 3833490970768671, 496100432831153},
+ {2222475519314561, 1870703901472013, 1884051508440561, 1344072275216753, 1318025677799069},
+ },
+ {
+ {4037612142179094, 2987286320918074, 5334840876971305, 3892287190264789, 5794263680951471},
+ {471926402845486, 2814813543274642, 3620200888572759, 1728489506884653, 3177161343196207},
+ {1819395223745913, 594758877920007, 1653753349717506, 242640844960873, 963869472910932},
+ },
+ {
+ {2936569169465705, 6049214516933086, 5963733906800640, 4231427100807371, 4853047066834829},
+ {2548596925868729, 2662135700065828, 2088163736824992, 2331981460676031, 2771125203890139},
+ {780634400476978, 637764048158951, 901014587909154, 1354805333992459, 2018934308296179},
+ },
+ {
+ {2797688906622325, 3428210403110380, 5022584852934687, 3295825468273441, 5705393166486691},
+ {2111199241475135, 1851629318616336, 1992578166276991, 2095428925801999, 1218266125748465},
+ {1810680242312559, 952287178947563, 681241246062059, 1252456339225424, 1959931529139639},
+ },
+ {
+ {4919536354167776, 4843044804249283, 4705930511557457, 5262690042745614, 4386984625976838},
+ {3747081830160208, 1520760409479969, 1598412209810121, 1654404133831532, 437659257098574},
+ {744124236937047, 1544378156616778, 715829909389559, 2120659842894185, 72002654880101},
+ },
+ {
+ {4563826663843359, 5185090504058247, 5145727029702249, 5011944329783380, 5313803489832094},
+ {244278499662023, 2000287644883357, 3512120660608951, 1998820466139820, 2107051881706162},
+ {1061541907539207, 1129143356143074, 459133314948729, 1177985907118634, 1224368687812524},
+ },
+ {
+ {3152842550820126, 4081984728409524, 3254259750651619, 4604329179757860, 4471438744025494},
+ {2383716445654654, 2845501105364248, 3179274641918483, 2181012191586748, 4055424112922904},
+ {1792270341351139, 2065266134997868, 51895527839218, 798734893906822, 992253836606399},
+ },
+ {
+ {4950351600164207, 5298895157252043, 5150281689404603, 4544152582549862, 5356669996354042},
+ {1927020266981541, 1747143248428675, 1588706088137551, 1077596294054796, 1170976366872068},
+ {1001666581039191, 1742276948383877, 1379478310433234, 767654427573973, 2047968425937961},
+ },
+ },
+ {
+ {
+ {4511412834337187, 4698043828798044, 4323205223211753, 5569204703546807, 6149086417101785},
+ {155711679280637, 681100400509288, 389811735211209, 2135723811340709, 2660533024889373},
+ {16625790644959, 1647648827778410, 1579910185572704, 436452271048548, 121070048451050},
+ },
+ {
+ {4694164895067901, 2924655519713304, 4842396181739721, 4841286895864398, 5356846476062228},
+ {3289062842237779, 2820185594063076, 2549752917829677, 3810384325616458, 2238221839292470},
+ {1763863028400139, 766498079432444, 1321118624818005, 69494294452268, 858786744165651},
+ },
+ {
+ {4869852729848717, 5029275869879305, 3701410808950684, 3435100659007430, 4689559933862040},
+ {3543856582248253, 1456632109855637, 3352431060735432, 1386133165675320, 3484698163879000},
+ {28315355815982, 460422265558930, 1799675876678724, 1969256312504498, 1051823843138725},
+ },
+ {
+ {4558284163736209, 4461809852221468, 5698584425525803, 5038838655144199, 3768154892986607},
+ {2408714813047231, 3857948219405196, 1665208410108429, 2569443092377519, 1383783705665319},
+ {1484387703771650, 198537510937949, 2186282186359116, 617687444857508, 647477376402122},
+ },
+ {
+ {4662985813836019, 4129426407048187, 5122336824431007, 5530273911701301, 3409921574477931},
+ {2147715541830533, 2751832352131065, 2898179830570073, 2604027669016369, 1488268620408051},
+ {1744544377739822, 1964054180355661, 1685781755873170, 2169740670377448, 1286112621104591},
+ },
+ {
+ {3854053602374273, 4943141672260381, 4472148111349729, 5161477038123364, 4661051199882732},
+ {2333777063470241, 3919742931398333, 3920783633320113, 1605016835177614, 1353960708075544},
+ {1029287186166717, 65860128430192, 525298368814832, 1491902500801986, 1461064796385400},
+ },
+ {
+ {3437283298068479, 3608139386273800, 5088531994686943, 4605732407316964, 6296522248487285},
+ {2660016802414475, 2121095722306988, 913562102267595, 1879708920318308, 2492861262121979},
+ {1966196870701923, 2230044620318636, 1425982460745905, 261167817826569, 46517743394330},
+ },
+ {
+ {6233793835087996, 4935389669690266, 6335114860649961, 3623880366453827, 5578113556752255},
+ {2358877405280588, 3136759755857592, 2279106683482647, 2224911448949389, 3216151871930471},
+ {1450880638731607, 1019861580989005, 1229729455116861, 1174945729836143, 826083146840706},
+ },
+ {
+ {3994140066248694, 3181522224560048, 3364322700715335, 6108496090134019, 4266308196944062},
+ {978398934730796, 1804963209584982, 2902083217855803, 2011728779166715, 3070976799182328},
+ {494691910923538, 1903565874798025, 2115181773831520, 2000771501496645, 2163753695162256},
+ },
+ {
+ {4499039401984510, 2919282610904813, 3371698570925682, 3170519001059914, 5250127479378489},
+ {1654039515014884, 2484661430680993, 2620692000541228, 2669599656280070, 2398652280696967},
+ {2019971150480802, 2112841493625261, 237154577131804, 1674207955014809, 1389703158284583},
+ },
+ {
+ {4706814366157303, 5336609175411517, 4757963599977030, 4060364649415927, 3640669095240911},
+ {780624938414169, 3404608320205059, 1982958325444026, 3570514777233615, 984254926012775},
+ {1463658959517057, 1983397723547684, 41055560978805, 424638764130418, 491755157953272},
+ },
+ {
+ {3257295355011901, 4096776962011503, 4487597369409850, 5876979850901767, 6030505591690325},
+ {2935104701953453, 3989681641092319, 3306366339882358, 2374391350196501, 1896075761392399},
+ {1262337399368722, 1039133447611747, 917288766852537, 1931663063827599, 386956994697158},
+ },
+ {
+ {5865485955051801, 4898975626365390, 5709055439582716, 3072783210395629, 4352817622936409},
+ {2724577252043037, 1050316213165918, 2370342271552724, 2792859709284319, 2760145987712013},
+ {1677351910521822, 152891770438727, 738510373109788, 1296476386064424, 1219545250565005},
+ },
+ {
+ {2955221061271345, 5973180148171190, 3740903689178612, 4255579446112404, 4178816467357894},
+ {1908022307626643, 2469819122662084, 1583327987932656, 3442462106139746, 599498145240366},
+ {220308000962909, 460573332431611, 732078470162760, 467340602781483, 1127652895548970},
+ },
+ {
+ {4256843681823156, 4695170685669586, 4012905106498514, 5492595949894092, 4822219141250098},
+ {1289113762003406, 2808167474320130, 1666802361626320, 1051654028271354, 1724653376239634},
+ {1695390634076771, 1517610099990508, 1248456812719894, 2178282202616225, 905038523003109},
+ },
+ },
+ {
+ {
+ {4388488268525257, 4351308814649541, 3942600308931722, 3469443492260723, 3080520458769465},
+ {1899935429242705, 1602068751520477, 940583196550370, 2334230882739107, 1540863155745695},
+ {765548025667841, 462473984016099, 998061409979798, 546353034089527, 2212508972466858},
+ },
+ {
+ {6305035755313584, 3986236631593136, 5772327717715563, 4670602724441205, 4485397579520202},
+ {2298375097456408, 3144370785258318, 1281983193144089, 1491520128287375, 75847005908304},
+ {1997562060465113, 1048700225534011, 7615603985628, 1855310849546841, 2242557647635213},
+ },
+ {
+ {3608844722049986, 2980930458947685, 6266068700289474, 3617433430563704, 4684882533775436},
+ {1161017320376250, 2744424393854291, 2169815802355236, 3228296595417790, 1770879511019628},
+ {1080413443139865, 1155205815510486, 1848782073549786, 622566975152580, 124965574467971},
+ },
+ {
+ {4272336182688229, 4705861119105631, 3304969482836130, 4308331792957791, 5281765142064806},
+ {1184526762066993, 247622751762817, 2943928830891604, 3071818503097743, 2188697339828084},
+ {237404399610207, 1308324858405118, 1229680749538400, 720131409105291, 1958958863624906},
+ },
+ {
+ {4785126936528543, 2288770346086770, 3118706734562790, 4474082416637981, 5793198356960377},
+ {2767383321724075, 2269456792542436, 1717918437373988, 1568052070792483, 2298775616809171},
+ {1278207464902042, 494742455008756, 1262082121427081, 1577236621659884, 1888786707293291},
+ },
+ {
+ {4316050955753838, 6170021230760201, 3671071179000687, 2720567588588102, 4695134757737078},
+ {353042527954210, 1830056151907359, 1111731275799225, 2426760769524072, 404312815582674},
+ {1716987058588002, 1859366439773457, 1767194234188234, 64476199777924, 1117233614485261},
+ },
+ {
+ {4802445580021739, 5669686216323056, 5683496153608928, 3599612573083939, 3664745203781455},
+ {3236091949205521, 2386938060636506, 2220652137473166, 1722843421165029, 2442282371698157},
+ {1143239552672925, 906436640714209, 2177000572812152, 2075299936108548, 325186347798433},
+ },
+ {
+ {4921698295511420, 2966865811406529, 3723715952061302, 4420370150973604, 5441412310007539},
+ {2972824668060020, 2936287674948563, 3625238557779406, 2193186935276994, 1387043709851261},
+ {1043584187226485, 2143395746619356, 2209558562919611, 482427979307092, 847556718384018},
+ },
+ {
+ {6539978005364395, 5005405360675302, 4390281321854973, 5817765520609028, 2885569505406129},
+ {2401607320460403, 912267207660896, 2797776548107885, 1401692837350636, 2770414290856347},
+ {904627574235583, 366582160013268, 1919276459982818, 683852563070972, 849013528013132},
+ },
+ {
+ {4382884022719489, 3331418080941236, 4472875449005139, 4019500438389598, 4463034067898545},
+ {314313360314847, 1556311374160012, 3420403310565817, 1814168775579274, 3865931899404825},
+ {2211811396782717, 1987727116500422, 1201194143426517, 1988979712261853, 884086138400803},
+ },
+ {
+ {3928195125806252, 4506628847593763, 4871806493038737, 5468133301160088, 4718975813247195},
+ {3157237349544610, 2087027997220233, 1635119994381095, 1685873597006198, 3264645977099821},
+ {554990822829571, 1043610604169755, 239155874009083, 1207029530220679, 1248980877883503},
+ },
+ {
+ {2330609380614712, 5282631639681642, 3679411410269759, 2770673432637308, 3778717181908177},
+ {2321085204756486, 3204498878947842, 1897195179818497, 2221896934640248, 2249233024322127},
+ {1100828805329651, 38323682820671, 233339076341529, 570439134676859, 373923102906827},
+ },
+ {
+ {4822469807205745, 4578534577854527, 3814578293772758, 6210971875752572, 3469875307698085},
+ {650556138336187, 1140806781381529, 1319490550148986, 2443218412602398, 2092597895198457},
+ {24874372349398, 672413878008022, 2109618619032869, 617580455983017, 643082448965145},
+ },
+ {
+ {3702942502950483, 4221261673998955, 4525315300848625, 5031967728773077, 4411934662665867},
+ {895116466708821, 2311360532554913, 1331906084934491, 1442649827370867, 985339602059253},
+ {1101806460504208, 48906420814555, 455540794156723, 777238833441277, 678815750013174},
+ },
+ {
+ {4956217544664282, 4411017504484405, 3654474138314413, 5155000128389593, 4413650344518487},
+ {1203258470211606, 2883266356628027, 1508156827359997, 3638270983429361, 1401834110583505},
+ {928961391578986, 832907369443124, 468987297840672, 1558723144077997, 1418280592841651},
+ },
+ },
+ {
+ {
+ {3309129437554730, 5123933694799617, 4965300486638528, 6516081243872351, 2549068382794184},
+ {1248731221520740, 1465200936117687, 2792603306395388, 2304778448366139, 2513234303861356},
+ {1055352180870759, 1553151421852298, 1510903185371259, 1470458349428097, 1226259419062731},
+ },
+ {
+ {4550600281784187, 3256554237859110, 4119844627242950, 4676836561429904, 5092370827107509},
+ {3744788603986897, 3042126439258578, 3441906842094992, 3641194565844440, 3872208010289441},
+ {30498470091663, 1082245510489825, 576771653181956, 806509986132686, 1317634017056939},
+ },
+ {
+ {5619235959382811, 4106140804649401, 4587392324740009, 4223977265679267, 2709254929742834},
+ {2672107869436803, 3745154677001249, 2417006535213335, 4136645508605033, 2065456951573058},
+ {1698968457310898, 1435137169051090, 1083661677032510, 938363267483709, 340103887207182},
+ },
+ {
+ {4745319008032005, 4813628148687644, 3467681137065440, 3660014790178871, 4392941970152610},
+ {1995325341336555, 911500251774648, 2415810569088940, 855378419194761, 3825401211214090},
+ {1315157046163473, 727368447885818, 1363466668108618, 1668921439990361, 1398483384337907},
+ },
+ {
+ {6557196758364187, 4276231499541578, 4485350770690107, 4264207089194792, 3124346806789687},
+ {2326829491984875, 3267188020145720, 1849729037055211, 4191614430138232, 2696204044080201},
+ {1217269667678610, 599909351968693, 1390077048548598, 1471879360694802, 739586172317596},
+ },
+ {
+ {4384302481090479, 4717978973545909, 3754548127453306, 4211871514743047, 3605771636328385},
+ {3970118453066023, 1560510726633957, 3156262694845170, 1418028351780051, 2346204163137185},
+ {319394212043702, 2127459436033571, 717646691535162, 663366796076914, 318459064945314},
+ },
+ {
+ {3198885719919217, 2575084544179354, 3737578377662447, 5232176448882889, 5405183975072780},
+ {2657789238608841, 1960452633787082, 2919148848086913, 3744474074452359, 1451061489880786},
+ {1575783124125742, 2126210792434375, 1569430791264065, 1402582372904727, 1891780248341114},
+ },
+ {
+ {5242752265626106, 4326735213088803, 5009083294116390, 3863683170199334, 2880454449080125},
+ {3090232019245924, 4249503325136911, 3270591693593114, 1662001808174330, 2330127946643001},
+ {1822054032121349, 643057948186973, 7306757352712, 577249257962099, 284735863382083},
+ },
+ {
+ {3757294655239106, 4149870483813681, 3943074023634421, 5011331412913659, 4204233544524725},
+ {765300458944758, 1962420935223063, 1006865922596525, 556125259357651, 517324314261719},
+ {947503289917657, 1503416272497360, 836151367440855, 2025240512839119, 1506056841382176},
+ },
+ {
+ {3987605469554571, 4216854847559852, 4606485208582710, 4025002076531210, 5771502720173311},
+ {789866795586711, 1219783998007690, 3399339961859034, 1430246873258510, 2263938746297911},
+ {272907227620417, 585056874977936, 374400386458564, 1047259762290717, 466584497787787},
+ },
+ {
+ {4513305810099276, 3713543936920641, 5881885803512264, 4985359422621344, 5854329220017841},
+ {2489594831593530, 2868670421452777, 2653264259914146, 778139640543916, 2896054888052141},
+ {67965761977879, 1140658137927248, 1433664110101982, 1907417172350895, 1009746387131234},
+ },
+ {
+ {4657525718512496, 4017020332264511, 5032007516852528, 4196574218153666, 4558814287479470},
+ {3191788312902362, 1662632170533261, 3849731434302862, 816384760006536, 2103376627071646},
+ {98516339668203, 1987095201806236, 109825731538912, 249333174781555, 868887613476084},
+ },
+ {
+ {4551570896172554, 4811478172541458, 3661911804185849, 2859956435208139, 3775782540863495},
+ {4251836217943410, 1527544805122594, 1416199226269029, 2604023934400523, 2761395386595757},
+ {1642831683324706, 1693640639567753, 543897185448748, 1014750779914025, 2000933536049400},
+ },
+ {
+ {5616692888384001, 4085181778999311, 5359480780192985, 4168165762634953, 3706985665716275},
+ {3046363118074651, 1033878254661623, 1432711896868579, 565399048183279, 1486610644259929},
+ {1956000744629083, 2124722115672587, 1869890027060221, 1779425010763214, 2251549887150752},
+ },
+ {
+ {5403435201118585, 6603374055023538, 4448450050924979, 4204020352279014, 3319690980306662},
+ {1147686993699695, 2183664403489392, 3736291649220767, 3475178747642004, 1656820196694734},
+ {993108364179144, 45592857828226, 1223718961690034, 1931120528549047, 1402978202475587},
+ },
+ },
+ {
+ {
+ {4707745854342560, 3882311012719969, 4467035027860010, 2426465723968789, 5459727301387711},
+ {3618358370049178, 1448606567552085, 3730680834630016, 2417602993041145, 1115718458123497},
+ {1562934578796716, 1070893489712745, 11324610642270, 958989751581897, 2172552325473805},
+ },
+ {
+ {2875482372335866, 3589666323156759, 5493912977577144, 3566036429447715, 3416572787955522},
+ {1770564423056008, 2987323445349813, 1326060113795288, 1509650369341127, 2317692235267932},
+ {223256821462517, 723690150104139, 1000261663630601, 933280913953265, 254872671543046},
+ },
+ {
+ {5739703102637456, 4089685696952464, 5529672212600950, 5529465141325467, 4053764715117380},
+ {1969087237026022, 2876595539132372, 1335555107635968, 2069986355593023, 3963899963027150},
+ {1115241013365517, 1712251818829143, 2148864332502771, 2096001471438138, 2235017246626125},
+ },
+ {
+ {4621952399709001, 5571208339175198, 5938396303563992, 3935039984233637, 4734466397277932},
+ {3551068012286861, 2047148477845620, 2165648650132450, 1612539282026145, 2765997725314138},
+ {1850689576796636, 1601590730430274, 1139674615958142, 1954384401440257, 76039205311},
+ },
+ {
+ {4398511437540326, 5006878555391994, 2877652875936652, 3360921192078354, 5537453437282356},
+ {1723387471374172, 3249101280723658, 2785727448808904, 2272728458379212, 1756575222802512},
+ {571005965509422, 2005213373292546, 1016697270349626, 56607856974274, 914438579435146},
+ },
+ {
+ {4021767746362864, 3947693133441663, 5655463017046415, 4032842598082935, 4903887401788780},
+ {1346698876211176, 2076651707527589, 3336561384795453, 2517134292513653, 1068954492309670},
+ {1851867764003121, 403841933237558, 820549523771987, 761292590207581, 1743735048551143},
+ },
+ {
+ {4789545034251916, 5151774024717947, 3350203576317227, 5870147068473486, 3757676696824463},
+ {410915148140008, 2107072311871739, 3256167275561751, 2351484709082008, 1180818713503223},
+ {672095903120153, 1675918957959872, 636236529315028, 1569297300327696, 2164144194785875},
+ },
+ {
+ {3867157095427632, 4907857238986876, 4412001163466224, 5664547006559450, 3829838433234787},
+ {1902708175321798, 3287143344600686, 1178560808893262, 2552895497743394, 1280977479761117},
+ {2013087639791217, 822734930507457, 1785668418619014, 1668650702946164, 389450875221715},
+ },
+ {
+ {5139170412209073, 4498594321446990, 3403045096731472, 3523999116931205, 4892973820656308},
+ {3100339582931283, 3780065035763732, 3107854667684806, 1176538847728659, 2470425204007084},
+ {1439699951361262, 2030141811121675, 1327540074439450, 98760879510567, 2124055188161162},
+ },
+ {
+ {5069757928527025, 4269771696870248, 3491008216607494, 2929486207919899, 2963259194922213},
+ {1719771161855965, 3899474813414394, 1311077187368436, 1710977333891379, 2936225820601205},
+ {630007537003875, 1879755431232807, 1841434412649072, 139825159320909, 1444684178970403},
+ },
+ {
+ {4165024628959566, 3986473160684857, 4482720357638229, 3477188964410991, 6063532098390286},
+ {2735367442263082, 3037388464741161, 708840305892227, 3376016746983163, 2424461132835430},
+ {1692345998026512, 1336264953003836, 472200476738834, 443198297543894, 865332172690922},
+ },
+ {
+ {3583240374232032, 6672838339902029, 3302719127491245, 4817707424315947, 3846209753841235},
+ {1940518928195986, 2204192709398575, 2559878786338619, 1240694154295451, 3150360999940643},
+ {978334155462452, 259156758770697, 1998397384612038, 868981902819036, 526720567050341},
+ },
+ {
+ {6295419175112392, 5922842429035919, 3280130237310527, 6154864010584464, 4672381744259604},
+ {2495384380697450, 2529087473815087, 3152074437283087, 2705660594301054, 3756859018180124},
+ {2829664309620, 1216345963700610, 1352213880784545, 1343440385603407, 1678896558555000},
+ },
+ {
+ {4462327178876654, 4861692839162759, 4026088282699843, 4559864737475196, 4141921357362458},
+ {970323584385428, 1841886145157987, 771455069751873, 2995416444511372, 1381697279273918},
+ {833881464516252, 722547189080954, 1385674139934263, 1947516117258013, 237073770273705},
+ },
+ {
+ {4933913084823421, 4670123363141682, 4900446203904881, 4055286352327374, 4290448492223496},
+ {2942776662601173, 2578009269314716, 544737250664645, 2975699597442162, 2099680134205576},
+ {452946908538500, 838029561099231, 448300214621162, 402872419278705, 704999550269611},
+ },
+ },
+ {
+ {
+ {5798682425720784, 4343644325181242, 6354948599958312, 4506974667055090, 5293040366083331},
+ {2705718263383616, 2358206633614248, 2072540975937134, 308588860670238, 1304394580755385},
+ {2083069137186154, 848523102004566, 993982213589257, 1405313299916317, 1532824818698468},
+ },
+ {
+ {4034211192773531, 5600324567335276, 4531193018091912, 2794041663976599, 3792137612125120},
+ {3747761112537659, 1397203457344778, 4026750030752190, 2391102557240943, 2318403398028034},
+ {693543956581437, 171507720360750, 1557908942697227, 1074697073443438, 1104093109037196},
+ },
+ {
+ {4735029189573542, 3778090050106418, 6524974691396918, 6024554123028535, 3058137605210362},
+ {345288228393400, 3351443383432420, 2386681722088990, 1740551994106739, 2500011992985018},
+ {1079623667189886, 872403650198613, 766894200588288, 2163700860774109, 2023464507911816},
+ },
+ {
+ {3748938635589832, 3296620064200837, 3994393700108731, 5740803740117332, 5352647078187481},
+ {854645372543796, 1936406001954827, 2403260476226501, 3077125552956802, 1554306377287555},
+ {667962773375330, 1897271816877105, 1399712621683474, 1143302161683099, 2081798441209593},
+ },
+ {
+ {3324209478486170, 4398737310762775, 3760579922605898, 5439367229755348, 5616400060914562},
+ {2378947665252234, 1936114012888109, 1704424366552046, 3108474694401560, 2968403435020606},
+ {333549023751292, 280219272863308, 2104176666454852, 1036466864875785, 536135186520207},
+ },
+ {
+ {5689714689958878, 4503409610653732, 5602544085249448, 3404912574886620, 4043425317102514},
+ {2625466093568366, 2398257055215356, 2555916080813104, 2667888562832962, 3510376944868638},
+ {1870078460219737, 2129630962183380, 852283639691142, 292865602592851, 401904317342226},
+ },
+ {
+ {3798100817109506, 4962694127433334, 3349468332060557, 6283897397500138, 2972563107372854},
+ {1361070124828016, 815664541425524, 3278598711049919, 1951790935390646, 2807674705520038},
+ {1212405311403990, 1536693382542438, 61028431067459, 1863929423417129, 1223219538638038},
+ },
+ {
+ {4842650611581872, 5104986353880267, 4917334859504562, 3217991068822474, 6343075526828654},
+ {1294303766540260, 3435357279640341, 3134071170918340, 2315654383110622, 2213283684565086},
+ {235605972169408, 2174055643032978, 1538335001838863, 1281866796917192, 1815940222628465},
+ },
+ {
+ {6283914285320299, 4538885684827819, 5272821644392905, 4741145486323262, 3695595414404375},
+ {2328903345630831, 383243669352281, 873975569357849, 1167517986625404, 1819176154401511},
+ {1015569285123052, 366271559910559, 607712860974980, 1151136439806917, 1092279314442070},
+ },
+ {
+ {4644837603275095, 4182486257496369, 5680847280055574, 5281364304268108, 4017310458808244},
+ {608363524539665, 1518910856395189, 2487752246555640, 1408491254860196, 1242950972146918},
+ {724510145626490, 1990648995683735, 1234513756420164, 776971151906420, 1819715569230741},
+ },
+ {
+ {4025210576522653, 5037391877366464, 6220723743247171, 4107687904850403, 5536810198272054},
+ {1367586897505451, 2009604536185136, 2660752171350541, 2665866783498593, 3368014404783418},
+ {1205287993924177, 1639266049462139, 1103796806037893, 1538960177870822, 829889727712499},
+ },
+ {
+ {4793558625576028, 3882027570562344, 4207241179173547, 5281023204511977, 6361433483438371},
+ {3281892459792280, 1933131048782198, 2351228493867205, 2032809616708977, 2534356983068777},
+ {909754464411828, 785219392684958, 1338541457752162, 826789969638535, 2048189131938215},
+ },
+ {
+ {5399590275296719, 3849598676683261, 3407829328170797, 4201689601652353, 3895190733841783},
+ {1015687460377127, 2173401063127799, 2017987633047477, 748955581941445, 630511527938929},
+ {2101074774193018, 2001243087608708, 801641610437734, 1519697986446082, 594845713523709},
+ },
+ {
+ {4827244732148509, 4706350784965857, 3625459412499055, 5917778693464512, 5372808769862558},
+ {1452942110247071, 1201823364506117, 2330240170803201, 2907618912660148, 2069141053434694},
+ {745779946397307, 916664696261756, 1535477642186117, 1334763610638931, 1366843744138046},
+ },
+ {
+ {4176014068905464, 4252766041468492, 3589174288259552, 3776062686798003, 4986282119113185},
+ {1092579010212274, 1203724605936750, 2270767453066752, 2458071886656347, 2443647576082745},
+ {318795329870799, 185430882319687, 1286511919273276, 657817007383756, 40641447918263},
+ },
+ },
+ {
+ {
+ {4538870843995520, 3964150480707053, 5487263883039355, 4602170887743532, 5736245235930330},
+ {1632352921721536, 1833328609514701, 2092779091951987, 4175756015558474, 2210068022482918},
+ {1998172393429622, 1798947921427073, 784387737563581, 1589352214827263, 1589861734168180},
+ },
+ {
+ {5350015016975595, 2997963309224426, 3081458566511327, 5095667333327441, 5460842165191887},
+ {1733739258725305, 2283515530744786, 2453769758904107, 3243892858242237, 1194308773174555},
+ {1758148849754419, 619249044817679, 168089007997045, 1371497636330523, 1867101418880350},
+ },
+ {
+ {3965982201013836, 5981456109444663, 5078495317312678, 4410918223912516, 3807332263401822},
+ {2578433797894864, 2513559319756263, 1700682323676192, 1577907266349064, 3469447477068264},
+ {853828206885131, 998498946036955, 1835887550391235, 207627336608048, 258363815956050},
+ },
+ {
+ {3753463041754121, 3606679279252159, 3696232489183494, 3149612277537848, 5358662226124843},
+ {2392941288336925, 3488528558590503, 2894901233585134, 1646615130509172, 1208239602291765},
+ {714380763546606, 1032824444965790, 1774073483745338, 1063840874947367, 1738680636537158},
+ },
+ {
+ {3423450128487239, 6070685071936072, 3705460605693651, 3009714346694508, 6123110970148691},
+ {1640635546696233, 2884968766877360, 2212651044092395, 2282390772269100, 2620315074574625},
+ {420958967093237, 971103481109486, 2169549185607107, 1301191633558497, 1661514101014240},
+ },
+ {
+ {5625132717515116, 5524850964392681, 4614069623317915, 3762859588443640, 4361835721816909},
+ {3158923465503550, 1332556122804145, 4075855067109735, 3619414031128206, 1982558335973171},
+ {303213233384524, 2061932261128138, 352862124777736, 40828818670255, 249879468482660},
+ },
+ {
+ {3697491154222530, 4544214010492622, 4905703930515359, 4988733897248726, 6163038950957920},
+ {856559257852200, 2760317478634258, 3629993581580163, 3975258940632376, 1962275756614520},
+ {20057458979482, 1183363722525800, 2140003847237215, 2053873950687614, 2112017736174909},
+ },
+ {
+ {2961281310713750, 5035281843536219, 4820563396802425, 4066115702139011, 4762159869794599},
+ {2228654250927986, 3735391177100515, 1368661293910955, 3328311098862539, 526650682059607},
+ {1053447823660455, 1955135194248683, 1010900954918985, 1182614026976701, 1240051576966610},
+ },
+ {
+ {3576347446000839, 3504021369715234, 3286921249007623, 6268908633911267, 4898262353027354},
+ {2053850994061963, 1755999209417110, 2842496597997123, 1978798188794297, 1107741233360060},
+ {1587558591633082, 1224310153016076, 373416710356490, 733639236443698, 365919571874338},
+ },
+ {
+ {4922046667787666, 5384603941382862, 3355282705253058, 5052638190916511, 4442324355401649},
+ {716350205934888, 1153032590403764, 2797021656648850, 1143194352934997, 4271302979058629},
+ {1588274760900072, 933817618340883, 731655082380959, 688238385999711, 637984915480250},
+ },
+ {
+ {4217060480329358, 4374528391636951, 5478312030233942, 5051281083802439, 5405881257383323},
+ {413138784837996, 173345891427747, 1873100191622562, 899752727618929, 3454430648436331},
+ {830072102529414, 1185948406051604, 1521170049452316, 1259798181998483, 735064905966282},
+ },
+ {
+ {5515669600102047, 5759134783811579, 4357089500282138, 5244472517255288, 5695631524373921},
+ {2842166480737527, 2947367283673209, 2706356593419314, 2971106642583260, 2444234893549177},
+ {1396164055858898, 2228551364195726, 611382817170935, 1662418665433346, 1079098567119990},
+ },
+ {
+ {3828208352345746, 5742603493540025, 5912515684826959, 5415942702105867, 4409414272784258},
+ {2895166868245672, 3153594867376981, 2883799413649215, 1877187137914547, 1124004944737352},
+ {1249379796419407, 1201460644559526, 1259226742776869, 583948750717161, 1178519968480157},
+ },
+ {
+ {4715510278636375, 4324771002227588, 4218850944267831, 4037187367673896, 4505301806813551},
+ {660737143139077, 1635830759165556, 795647058595473, 2117049403264300, 2692853476865573},
+ {1654844956375931, 767321709128720, 475080629455448, 116932684758291, 96451917556060},
+ },
+ {
+ {5797033177541322, 5021581754974953, 4978830133961786, 5973534325336756, 4105099431310062},
+ {1777561190222404, 3757586069945925, 2868096822929350, 1968746982919962, 1089633650980574},
+ {833672890421142, 647759906668054, 572517465546269, 402134952667751, 2083275174687780},
+ },
+ },
+ {
+ {
+ {6352542060466074, 3833809696215741, 4101092554705390, 3320298136988035, 4253202043484731},
+ {1957943897155478, 1788667368028035, 2389492723714354, 2252839333292309, 3078204576998275},
+ {1528282417624269, 2142492439828191, 2179662545816034, 362568973150328, 1591374675250271},
+ },
+ {
+ {4265077968872559, 2914460285039701, 3045781039391514, 4915306233356239, 5308090560495285},
+ {2411826493119617, 2484141002903963, 2149181472355544, 598041771119831, 2435658815595421},
+ {2051892037280204, 488391251096321, 2230187337030708, 930221970662692, 679002758255210},
+ },
+ {
+ {3713635732994642, 4207056293821675, 4684465815183558, 6055578880035022, 5061343489334444},
+ {1530723630438670, 875873929577927, 2593359947955236, 2701702933216000, 1055551308214178},
+ {359179641731115, 1324915145732949, 902828372691474, 294254275669987, 1887036027752957},
+ },
+ {
+ {4324702538941745, 2563932266428659, 4813530513012704, 5499843939988947, 3842301114037549},
+ {4295071423139571, 2038225437857463, 1317528426475850, 1398989128982787, 2027639881006861},
+ {1397254305160710, 695734355138021, 2233992044438756, 1776180593969996, 1085588199351115},
+ },
+ {
+ {4202522275076530, 6411445226225292, 4074557295320773, 4373367518435491, 4577411558841716},
+ {2692366865016258, 2506694600041928, 2745669038615469, 1556322069683365, 3819256354004466},
+ {387139307395758, 2058036430315676, 1220915649965325, 1794832055328951, 1230009312169328},
+ },
+ {
+ {3379372614866712, 3476543574256943, 5779819517217769, 3781538535387827, 3841619480557100},
+ {1765973779329498, 2911143873132225, 2271621715291913, 3553728154996461, 3368065817761132},
+ {2181229378964934, 2190885205260020, 1511536077659137, 1246504208580490, 668883326494241},
+ },
+ {
+ {4227237865914097, 5575401147370301, 5098251926594813, 4129497466354055, 3741435180672532},
+ {2689666469258543, 2920826224880015, 2333696811665585, 523874406393177, 2496851874620484},
+ {958592545673770, 233048016518599, 851568750216589, 567703851596087, 1740300006094761},
+ },
+ {
+ {3792569420294954, 4400089757531324, 6101403783497940, 5734203344054362, 3067223272494699},
+ {2014540178270324, 192672779514432, 2465676996326778, 2194819933853410, 1716422829364835},
+ {1738560251245018, 1779576754536888, 1783765347671392, 1880170990446751, 1088225159617541},
+ },
+ {
+ {4447695422728303, 2418292515870024, 5595971144063629, 5081870838292807, 5209525481880645},
+ {2916521632160477, 2343112140697014, 1601700300762337, 1763148914953177, 2708190975156259},
+ {1339021042945816, 1840804708066696, 877961221559635, 1281458842745501, 1950851850845276},
+ },
+ {
+ {4786922334540966, 4955024641438784, 2989160972656404, 5186429632708936, 4984389249074409},
+ {1020393680308960, 3834711966547082, 2322726956159582, 995949551108034, 3035172379117141},
+ {2248087612518599, 173333799263920, 1744928838552182, 957368524885377, 1722980339454003},
+ },
+ {
+ {3826226586501329, 4985391470235567, 3706778387862153, 5001039432994919, 3643485069381971},
+ {2453664361158331, 3658664111645897, 2133047286876873, 2891246599919261, 1077039773701841},
+ {1403674776792037, 176114870970230, 204752269254815, 823265703401663, 973549049711641},
+ },
+ {
+ {4428694302478430, 4279516097530892, 4558829707092394, 4506689423374814, 3060727770678082},
+ {3511507258617268, 2341694334736402, 3023178443373630, 4119452783133958, 1541883672814480},
+ {273175012476053, 353915697751570, 1920076197363975, 2096923665433891, 694182114426694},
+ },
+ {
+ {4184692084971979, 4134060280811983, 3170779668973105, 4456307003709940, 4308299286729100},
+ {2273158812011175, 3253770145986191, 1455430838863125, 1701216872600126, 1994907074166318},
+ {854928709890819, 247698160098706, 1293104197995963, 648230677212306, 784063325867838},
+ },
+ {
+ {4504036913969323, 5450574207835078, 6042071388766678, 4918868602774744, 5356088910233627},
+ {2995726671480383, 3106924626287182, 2718750693945174, 3268809265740618, 1129470954185503},
+ {2104894828289916, 873144584667742, 506537740149646, 646077767532773, 1966868865211605},
+ },
+ {
+ {6048446108790732, 5524115631172029, 4165751037432881, 4331639016561072, 5291322591785068},
+ {2269347023399866, 1910686315635227, 654955394153571, 2857416503175088, 847850165913280},
+ {836953051260559, 1769743545147988, 699239118029628, 825806019782225, 1990070083297713},
+ },
+ },
+ {
+ {
+ {3395265304118584, 3783994539881306, 5596876372865192, 4984641333486582, 4373205247246409},
+ {2911103727614740, 1956447718227572, 1830568515922666, 3092868863429656, 1669607124206367},
+ {1686424298744462, 1451806974487153, 266296068846582, 1834686947542675, 1720762336132256},
+ },
+ {
+ {3458195995174227, 4836757775805549, 3654433306506668, 5623690819092521, 4197273928235755},
+ {3141016840074207, 3295090436969907, 3107924901237156, 1669272323124635, 1603340330827879},
+ {766720088232571, 1512222781191002, 1189719893490790, 2091302129467914, 2141418006894941},
+ },
+ {
+ {5441759705376431, 3673576132738420, 4193443048427021, 4683601810691313, 3666180150435792},
+ {2671463460991841, 1998875112167986, 3678399683938955, 3406728169064757, 2738338345823434},
+ {398001940109652, 1577721237663248, 1012748649830402, 1540516006905144, 1011684812884559},
+ },
+ {
+ {3248461355092589, 5959477015323422, 2996112620542523, 4642813523567241, 5503882535918283},
+ {1653276489969611, 2257881638852872, 1921777941170835, 1604139841794531, 3113010867325889},
+ {1450817495603008, 1476865707053229, 1030490562252053, 620966950353376, 1744760161539058},
+ },
+ {
+ {3213965769821056, 5620199287619286, 4685689805377309, 5959205094392245, 4699653216173778},
+ {2811528223687828, 2288856475326432, 2038622963352005, 1637244893271723, 3278365165924196},
+ {796863823080135, 1897365583584155, 420466939481601, 2165972651724672, 932177357788289},
+ },
+ {
+ {4468743695984567, 4898440950560817, 4474456712004917, 5061786181321024, 3329036690710436},
+ {877047233620613, 1375632631944375, 2895573425567369, 2911822552533124, 2271153746017078},
+ {801118384953213, 1914330175515892, 574541023311511, 1471123787903705, 1526158900256288},
+ },
+ {
+ {3726318200450545, 4012593435854444, 5660999417843231, 3874664121744144, 4669027921793287},
+ {3201417702772463, 2207116611267330, 3164719852826535, 2752958352884036, 2314162374456719},
+ {1961673048027128, 102619413083113, 1051982726768458, 1603657989805485, 1941613251499678},
+ },
+ {
+ {3486506407007189, 5586943518586412, 3150073788000181, 3892658932084745, 4661178025941644},
+ {1401939116319247, 2587106153588320, 2323846009771033, 862423201496005, 3102318568216632},
+ {1143483057726416, 1992614991758919, 674268662140796, 1773370048077526, 674318359920189},
+ },
+ {
+ {5249032546684913, 4376477734728695, 5192833668695386, 3879528383130666, 4673544232718438},
+ {2001586827113779, 3745189534067065, 1944288247515270, 3801531181100442, 2035001711257644},
+ {1821331151892312, 1302058705892077, 1823533497142581, 1477427445977593, 1256884978338733},
+ },
+ {
+ {3816568398797501, 4280523703434080, 5575370580457579, 6556193442157265, 5400032142723120},
+ {3676887960291627, 2721875544375886, 1949386962401535, 2062484445640651, 1831148391448868},
+ {1098621584553762, 479766126028979, 50128556582829, 1793185955386011, 957643491878541},
+ },
+ {
+ {5624964178025902, 5881679035334285, 5337334188128135, 3373245272349238, 6030340196395357},
+ {1686491261026354, 2930481776329103, 2527067703865047, 1879410757156738, 2416602562794561},
+ {1954783342191961, 1776196854323048, 1073865783628317, 126006585556188, 551111053703277},
+ },
+ {
+ {5863020639436884, 5014608403303800, 3487461172336056, 4625089084538493, 3002443292699384},
+ {1844293295362196, 3776383490821424, 1827935191421176, 1761145652561373, 2654244832682184},
+ {2163920127813722, 1809848067831371, 1226486593520438, 6568253441272, 318658165188350},
+ },
+ {
+ {5229528028782988, 3740161041125714, 3628427289315213, 5072860979211871, 5962952384148406},
+ {1112209403436618, 3603724598892882, 3004743983803641, 1636637612372587, 1910870598142670},
+ {1139920697586991, 989775023258908, 1562720488536799, 1457380545841604, 910097567659210},
+ },
+ {
+ {3041059796685021, 3926553231646481, 4587262528244901, 5282743084605635, 4777345624727557},
+ {2431004626164709, 3854783312160059, 3273298459729433, 3386841277003151, 3777213922766615},
+ {295894405919626, 1325594150172422, 673838771367222, 604280180076012, 485577818727658},
+ },
+ {
+ {3793091552131313, 4374989255749447, 4298473526457935, 3586546830561382, 4785727997920673},
+ {3556189185732659, 4013352737062889, 2854416081619439, 1896415948116520, 654670146226537},
+ {139962000945005, 2246840272939065, 40902718655534, 1533074280944617, 1032382655251714},
+ },
+ },
+ {
+ {
+ {3758431901841840, 4379281609207426, 5017412546860750, 4644243343298864, 4946076247670812},
+ {1835401379538542, 173900035308392, 818247630716732, 4013900225838034, 1021506399448290},
+ {2056683376856736, 219094741662735, 2193541883188309, 1841182310235800, 556477468664293},
+ },
+ {
+ {4597695873914911, 5426082008537486, 4528117456116057, 4391230322227749, 4348938857916251},
+ {3566819241596075, 1049075855992602, 4318372866671791, 2518704280870781, 2040482348591519},
+ {537697207950515, 1399352016347350, 1563663552106345, 2148749520888918, 549922092988516},
+ },
+ {
+ {4827183563480027, 4225372812262903, 3444018843651805, 4582954431755768, 5877642652930841},
+ {1747985413252415, 680511052635695, 1809559829982725, 2846074064615302, 2453472984431229},
+ {213277331329947, 416202017849623, 1950535221091783, 1313441578103244, 2171386783823658},
+ },
+ {
+ {6124178045615487, 5044634958558963, 4487585538139111, 4406665622773445, 4226427082437073},
+ {2440888617915079, 993969372859109, 3147669935222235, 3799101348983503, 1477373024911349},
+ {1346805451740245, 1350981335690626, 942744349501813, 2155094562545502, 1012483751693409},
+ },
+ {
+ {3326465926121696, 4752879014110088, 3426137740310600, 3810813345691727, 3724087589204368},
+ {2107080134091762, 1132567062788208, 1824935377687210, 769194804343737, 1857941799971888},
+ {1872620123779532, 1892932666768992, 1921559078394978, 1270573311796160, 1438913646755037},
+ },
+ {
+ {3280128640868324, 3962843103655104, 3602632284060180, 4174964503289574, 5999255996217406},
+ {3089190001333428, 3264053113908846, 989780015893986, 1351393287739814, 2580427560230798},
+ {1900828492104143, 430212361082163, 687437570852799, 832514536673512, 1685641495940794},
+ },
+ {
+ {5679936010824454, 3977277108025017, 4516300250042949, 2929815522503454, 4666323705890374},
+ {3094432661621646, 605670026766215, 290836444839585, 2415010588577604, 2213815011799644},
+ {1448049969043497, 1789411762943521, 385587766217753, 90201620913498, 832999441066823},
+ },
+ {
+ {3515424710267724, 5606202029043823, 5029901811084866, 4403815652814045, 3735639122175257},
+ {2767886146978542, 2240508292484615, 3603469341851756, 3475055379001735, 3002035638112385},
+ {442991718646863, 1599275157036458, 1925389027579192, 899514691371390, 350263251085160},
+ },
+ {
+ {5324956849177719, 3429271620480873, 5513927382492506, 4069478768490913, 4487763984887828},
+ {1005736577196489, 1703778335600507, 1256787933200658, 1273583601164519, 4154995520392582},
+ {1181460621741892, 515102888370257, 660560226785527, 1121970691511835, 1609869229541589},
+ },
+ {
+ {5276536763892090, 4684953471965519, 6139261731383556, 3763310979241977, 3999629994843744},
+ {3197840386614072, 2673429719431285, 2328666993391622, 1601604658039797, 754388419948612},
+ {2189230067083086, 574898679774723, 1093556583385601, 1590603941933467, 1876625616519950},
+ },
+ {
+ {3739860822512771, 4605148533211466, 4174048138272099, 4387338734269228, 2880424850917010},
+ {2359748764236743, 2750393191088290, 1526008165088803, 1669725971211966, 2233234520219112},
+ {42208074517808, 919916618772548, 1864146060012263, 405874007551625, 167276017170589},
+ },
+ {
+ {4682022353746882, 6009429539947866, 2947942480787000, 5087407628431820, 4667285753466106},
+ {1939674698340922, 2060465757190214, 2418157875657274, 1687699771189262, 236132178171812},
+ {674205207435332, 837990472116301, 1170756550883494, 611962296440926, 1446026806940794},
+ },
+ {
+ {4797835609201808, 3649645875831679, 5195894411777247, 3424984715982399, 5322304250778016},
+ {3454576586408064, 2256192384569215, 2864444376813541, 2134820396191597, 1047034985188490},
+ {1582224761030916, 260261512990929, 1131518591198333, 94648525453241, 270083062170054},
+ },
+ {
+ {5595107036983877, 4494054900752656, 3263812520261324, 5044525307237686, 3722017695712965},
+ {1188525422166779, 3589855283768506, 1782193012394260, 2155228647422980, 3120862178456839},
+ {1981581840102891, 142303636665554, 2039535378650111, 1181156234198923, 1967834468546111},
+ },
+ {
+ {5706915977082882, 3753081378072469, 2510190141605996, 4045103810631250, 4992176450645285},
+ {1947964231400572, 2169451112529873, 2463002605422706, 3228930307152278, 597158871609891},
+ {1385883488372791, 1890958046379947, 2126979282588918, 17215697802179, 562809648160246},
+ },
+ },
+ {
+ {
+ {6060806645993160, 4844231320170097, 3729525723161433, 2866535765304666, 4285036937432013},
+ {1689713572022124, 2845654372939621, 3229894858477217, 1985127338729498, 3927868934032873},
+ {968764929340557, 1225534776710944, 662967304013036, 1155521416178595, 791142883466590},
+ },
+ {
+ {5626780938473300, 5189175572245936, 2759405279195173, 3664390275802720, 2819817138913873},
+ {1487081286167458, 3244839255500182, 1792378982844639, 2950452258685122, 2153908693179753},
+ {560258797465417, 2193971151466401, 1824086900849026, 579056363542056, 1690063960036441},
+ },
+ {
+ {4383124982462505, 3428436472114155, 6260522268883476, 3642043430861258, 4218124990723630},
+ {1918407319222397, 2605567366745211, 1930426334528098, 1564816146005724, 4113142195393344},
+ {2063958120364491, 2140267332393533, 699896251574968, 273268351312140, 375580724713232},
+ },
+ {
+ {4285699823073660, 3996702683556035, 4442379901602887, 6453074611624616, 4734649381664242},
+ {2024297515263178, 2668759143407935, 3330814048702549, 2423412039258430, 1031677520051052},
+ {343868674606581, 550155864008088, 1450580864229630, 481603765195050, 896972360018042},
+ },
+ {
+ {6032529693711055, 6108603534430070, 3306860895022921, 5961918729318160, 5737795472583636},
+ {2151139328380127, 2566545695770176, 2311556639460451, 1676664391494650, 2048348075599360},
+ {830430507734812, 1780282976102377, 1425386760709037, 362399353095425, 2168861579799910},
+ },
+ {
+ {3935550130401342, 5155878315656623, 3473598574878785, 4149160495161916, 4823257793397838},
+ {3407562046415562, 980662895504005, 2053766700883521, 2742766027762854, 2762205690726604},
+ {618808732869972, 72755186759744, 2060379135624181, 1730731526741822, 48862757828238},
+ },
+ {
+ {4481933078376341, 5067550582461519, 4294715789111644, 5330913983663967, 5175628607523309},
+ {3714971784278753, 3394840525452699, 614590986558882, 1409210575145591, 1882816996436803},
+ {264204366029760, 1654686424479449, 2185050199932931, 2207056159091748, 506015669043634},
+ },
+ {
+ {4317070754263612, 4535076723640848, 4810021506483985, 4685558271307180, 4158905350371329},
+ {1784446333136550, 1973746527984364, 334856327359575, 3408569589569858, 3275749938360725},
+ {1496516440779464, 1748485652986458, 872778352227340, 818358834654919, 97932669284220},
+ },
+ {
+ {3850207796558603, 3727422831028406, 3797434477252654, 4293213262701836, 4516227523843066},
+ {2048146359190201, 2164495845485630, 1987127118350888, 3702022928556186, 1248356726771194},
+ {1517919028451878, 1390653207300047, 480997424969526, 463880049786815, 1566994328535414},
+ },
+ {
+ {4207292859242158, 4439237956877375, 6466630861755493, 6117169411664878, 6203775439423042},
+ {2630289459558480, 2051409995957989, 2137890426251559, 2865150520767226, 2183646505352378},
+ {250950165450403, 2108575357747549, 1858230594483734, 184468003072844, 1358638013010624},
+ },
+ {
+ {4795165927742161, 3556821674590553, 4452234877886028, 4063350508177236, 4357194618603124},
+ {1363161060275889, 2019577584627825, 655391965916958, 2833727353647238, 2341948580614770},
+ {1778982619924496, 1328609079558951, 1163827266617015, 1019320353990254, 830400209170522},
+ },
+ {
+ {3688756718408583, 4561393289356786, 5750092980695080, 4477840229539135, 3932387371938841},
+ {891039147350711, 498786796467410, 3025350790192290, 652448826471937, 3394872208963829},
+ {913282769158846, 347533899935257, 99606006705773, 1452035970297517, 2212487011762079},
+ },
+ {
+ {3066351608928554, 4959266561713426, 3505484480779672, 3313237988086280, 3214107063996871},
+ {2440372328053980, 3986555651364494, 2478020726949882, 3029257951861872, 1322928669372349},
+ {1259703414196061, 804804682694258, 2147323977049515, 252131006189623, 2246814133555350},
+ },
+ {
+ {4603288585029083, 4275494842669350, 4559975392494094, 5326825482142171, 4885471931566349},
+ {616470521493849, 390707946935204, 1334622907385598, 2029831529830923, 2813735341554671},
+ {1307353080865175, 1065210115652369, 1698012640184922, 2095589265946492, 688919666182564},
+ },
+ {
+ {4119409763828209, 5174415249772511, 6589359183715483, 3474134685034925, 3261800548024222},
+ {3800663179733707, 1510662538907767, 2305029203181277, 1120480520235783, 2745749397969076},
+ {959187641997964, 1919963359331922, 1067802756608566, 851276549968152, 2180947835690309},
+ },
+ },
+ {
+ {
+ {5516816602304168, 5042521547053092, 4167576536206804, 6246422068954372, 4138350501601902},
+ {2723435829455580, 2924255216478824, 1804995246884102, 1842309243470804, 3753662318666930},
+ {2094270000643336, 303971879192276, 40801275554748, 649448917027930, 1818544418535447},
+ },
+ {
+ {5719674169295574, 4553720561304003, 3817628817819056, 2973527969819827, 4852805692036683},
+ {2241737709499146, 549397817447461, 838180519319392, 1725686958520781, 3957438894582995},
+ {948617110470858, 346222547451945, 1126511960599975, 1759386906004538, 493053284802266},
+ },
+ {
+ {4357186931049660, 4248263218811680, 5806608241664995, 5355507743318703, 5857341677159129},
+ {1454933046815146, 3126495827951610, 1467170975468587, 1432316382418897, 2111710746366763},
+ {750300956351719, 1487736556065813, 15158817002104, 1511998221598392, 971739901354129},
+ },
+ {
+ {3486884278433110, 3417910960117329, 3997194671566838, 3657316287568287, 4508063131522112},
+ {1874648163531674, 2124487685930551, 1810030029384882, 918400043048335, 2838148440985898},
+ {1663810156463827, 327797390285791, 1341846161759410, 1964121122800605, 1747470312055380},
+ },
+ {
+ {4458441089863460, 3942387623406751, 3851973436510373, 4407895911319668, 3358622222233463},
+ {660005247548214, 2071860029952887, 3610548013635355, 911703252219106, 3266179736709079},
+ {1344788193552206, 1949552134239140, 1735915881729557, 675891104100469, 1834220014427292},
+ },
+ {
+ {5125820669443841, 3461946287724414, 3994046236028930, 5907438988749520, 4920789118266230},
+ {1920949492387945, 2410685102072778, 2322108077349280, 2877838278583064, 3719881539786256},
+ {22727256592983, 168471543384997, 1324340989803650, 1839310709638189, 504999476432775},
+ },
+ {
+ {3589266475777094, 5791244982040267, 6521619274146678, 2903981043059491, 5401611380582210},
+ {3565040332441556, 1721896294296941, 2304063388272514, 2065069734239231, 3056710287109878},
+ {1969792547910734, 779969968247557, 2011350094423418, 1823964252907487, 1058949448296945},
+ },
+ {
+ {5777164948769480, 3890309495649820, 5262835493859430, 5169614751717201, 5401583088313899},
+ {2459143550747250, 1118176942430252, 3010694408233412, 806764629546265, 1157700123092949},
+ {1717263794012298, 1059601762860786, 1837819172257618, 1054130665797229, 680893204263559},
+ },
+ {
+ {2942680342150880, 4278613828995852, 5350213167690156, 2989120782966715, 4123142629949771},
+ {2556444502235146, 1613361869622030, 1402717375340694, 2348339985765731, 3489511500408293},
+ {1426750262638336, 314863572574246, 1394348337483702, 1967765724676815, 1262927622887481},
+ },
+ {
+ {4948972567610721, 4760459340435499, 4508373064131856, 4400791580495755, 3326118030989422},
+ {2602109836867459, 1003276938441793, 244450874677932, 2495574856155249, 3110870831093824},
+ {1089876164348856, 610853718362589, 290946077126125, 1189633635903067, 238116851513210},
+ },
+ {
+ {5818313990376412, 3745131403850386, 4984633161305300, 4588134365279068, 5605706152381173},
+ {2574353462387544, 1744531678913296, 2081810750651984, 1255482175291668, 1579377192487289},
+ {1077984189936462, 1101581309304165, 229118769946835, 213129071862971, 1105903869282826},
+ },
+ {
+ {4244657319305304, 4848112240284328, 4808999745724375, 4645297205085174, 4469873257565411},
+ {2568686941901236, 1277107033850968, 2743723193537219, 3580901504461986, 430697021449829},
+ {5110283730621, 236925008060043, 590130982419942, 541274580551940, 2155487465178420},
+ },
+ {
+ {4504922761302740, 3620992509914934, 3198533798350925, 3770782329534318, 5363163230411568},
+ {275387113122210, 3501532982637668, 2704624275342757, 1489585626413894, 3573009822045302},
+ {1859877583133149, 1445451213294944, 309288119160981, 1843441717427399, 584114977316234},
+ },
+ {
+ {4103673694186728, 6461574165907240, 3718162222127163, 6247603847194471, 5772831446786927},
+ {2087653679988656, 2238424089144458, 2130407033226307, 1889280872742259, 2146873922212313},
+ {500701236542790, 1839091700792145, 218488889984877, 1301749778593414, 614810966957821},
+ },
+ {
+ {4649730463510780, 3151390162038927, 5365410818081747, 5007340477551264, 5551016597277571},
+ {2300360039943938, 1529233553127717, 3500096717284879, 3664531564773424, 3173693672061933},
+ {882756809520167, 998774482479105, 593908492257531, 1132796830151366, 1780707297956298},
+ },
+ },
+ {
+ {
+ {4583071810090063, 6354729884420668, 4077544622618353, 3073467147166315, 5285394920882441},
+ {2237039662793603, 2249022333361206, 2058613546633703, 2401253908530527, 2215176649164581},
+ {755822026485370, 152464789723500, 1178207602290608, 410307889503239, 156581253571278},
+ },
+ {
+ {3747179848085639, 4828649103787668, 4549946522264427, 3805208654040102, 5332579729206178},
+ {3669985309815545, 2736319981413860, 3898537095128197, 3653287498355512, 1349185550126960},
+ {1280337889310282, 2070832742866672, 1640940617225222, 2098284908289951, 450929509534434},
+ },
+ {
+ {5758557848470941, 5656835588370337, 3194707518654080, 2888905217772639, 5652892897517762},
+ {2659503167684029, 2378371955168899, 2537839641198868, 1999255076709337, 2030511179441770},
+ {894249020470196, 400291701616810, 406878712230981, 1599128793487393, 1145868722604026},
+ },
+ {
+ {4956087140669123, 3603920362709815, 3425295697596203, 4250911519607256, 4870927757824721},
+ {3749755063888563, 2361916158338507, 1128535642171975, 1900106496009660, 2381592531146157},
+ {1717539401269642, 1475188995688487, 891921989653942, 836824441505699, 1885988485608364},
+ },
+ {
+ {4274232174887052, 5592415718055546, 4229643212225114, 4106634029575971, 5067838489399852},
+ {3493583935107776, 2439136865632830, 3370281625921440, 2680547565621609, 2282158712612572},
+ {938868489100585, 1100285072929025, 1017806255688848, 1957262154788833, 152787950560442},
+ },
+ {
+ {3546872176125197, 5434827532059909, 3607531246326933, 5425835363204530, 5395826856780703},
+ {3119119231364171, 2872271776627789, 2477832016990963, 2593801257642876, 1761675818237335},
+ {1680989767906154, 535362787031440, 2136691276706570, 1942228485381244, 1267350086882274},
+ },
+ {
+ {2787309244260446, 2798685347422569, 6028275236918294, 4389895566536949, 3512537903582074},
+ {2617818047455756, 2684460443440843, 2378209521329782, 1973842949591661, 2897427157127624},
+ {1159906385590467, 2198530004321610, 714559485023225, 81880727882151, 1484020820037082},
+ },
+ {
+ {4265412029331945, 4082570389605622, 2787935123905079, 2861072139265641, 4774283971865508},
+ {1377485731340769, 2046328105512000, 1802058637158797, 2313945950453421, 1356993908853900},
+ {1237542585982777, 2228682050256790, 1385281931622824, 593183794882890, 493654978552689},
+ },
+ {
+ {4433747840806046, 3721621780348463, 4999137013220096, 4950695012032930, 2963731882329120},
+ {3700733741689868, 2019165860436683, 839545028551310, 954045289946680, 2857671609142350},
+ {2031235379883797, 946220755552074, 1457648474415011, 1222951728743327, 1610191601040290},
+ },
+ {
+ {4162295633314539, 4747504508371898, 5420102803358852, 5241263790326999, 4652112494046944},
+ {3713236670706339, 1708249553383010, 1441184960961852, 2138372449656361, 2208801341603864},
+ {743176047113998, 1210025633688996, 1298930577649249, 2241929289171655, 319185600078644},
+ },
+ {
+ {2463674019917897, 4802840710289795, 3812247475965604, 5281339404908102, 6114735096224475},
+ {2361755477281753, 3920079557094249, 1772761852174940, 2188727617473580, 1972330964627961},
+ {2224894613062235, 459022333460366, 853633232091964, 42662368548958, 1428459390829900},
+ },
+ {
+ {5876939711261840, 5483557082287477, 3340896169956977, 4741202975388493, 3246978129870096},
+ {1888400628800904, 3246442970371919, 2048876033526183, 418388094414663, 2174354817875660},
+ {1865410028261408, 627467389699032, 146077987303115, 1698467014229834, 2014393109530681},
+ },
+ {
+ {3339126822971782, 5967460547143544, 4911389289674917, 4202215034765918, 5578073611339204},
+ {2670644791837462, 2651763434193316, 2285020046276825, 2227807589256768, 1464013488829088},
+ {1806473647942365, 538787999504182, 512973154409687, 1944932181085518, 1069910541821032},
+ },
+ {
+ {2634758329364868, 4859512915801802, 4928387675794414, 4438135586288705, 5912306986153546},
+ {2593937978996354, 2409464365976668, 2076140577147016, 4427101675063297, 1879995664155906},
+ {407209884855019, 2088464831333939, 2111856537862679, 1631244096914416, 1074707055277992},
+ },
+ {
+ {4379690451347501, 4147722372858437, 6043474882489476, 3830885552726038, 5483938823325814},
+ {502401202015803, 2110371415921011, 2529666734456328, 2767243204597450, 2341774206366416},
+ {1547018311600067, 615783499206767, 485547569767288, 1517514580034299, 457611163959317},
+ },
+ },
+ {
+ {
+ {6197629798333913, 2753838380751446, 3942959878910714, 3201428133247434, 4778709814063561},
+ {2299141301692989, 1891414891220256, 983894663308928, 2427961581972066, 3378060928864955},
+ {1124515748676336, 1661673816593408, 1499640319059718, 1584929449166988, 558148594103306},
+ },
+ {
+ {3540740886557976, 3183587715724649, 4694330636229537, 4258659768352436, 5509531109592197},
+ {1784525599998356, 1619698033617383, 2097300287550715, 2510065271789004, 1905684794832757},
+ {1465551264822703, 152905080555927, 680334307368453, 173227184634745, 666407097159852},
+ },
+ {
+ {4674947851286115, 5166365727170883, 4965938571130991, 4970517390710808, 2908711106554361},
+ {2111017076203943, 3630560299479595, 1248583954016455, 3604089008549670, 1895180776543895},
+ {488623681976577, 866497561541722, 1708105560937768, 1673781214218839, 1506146329818807},
+ },
+ {
+ {5492578995360943, 3611529141261548, 3553634070931276, 4797740788199803, 4532947899647969},
+ {2412225278142205, 950394373239688, 2682296937026182, 711676555398831, 320964687779005},
+ {1434382743317910, 100082049942065, 221102347892623, 186982837860588, 1305765053501834},
+ },
+ {
+ {3443537155111802, 4098841848663610, 3634013358734303, 3291752209395695, 5292412486267354},
+ {2205916462268190, 2751663643476068, 961960554686615, 2409862576442233, 1841471168298304},
+ {1346965964571152, 1291881610839830, 2142916164336056, 786821641205979, 1571709146321039},
+ },
+ {
+ {4996047770903428, 2555904966356003, 4013566981986303, 4737382312068285, 4233095136791335},
+ {787164375951248, 2454669019058437, 3608390234717387, 1431233331032509, 786341368775957},
+ {665807507761866, 1343384868355425, 895831046139653, 439338948736892, 1986828765695105},
+ },
+ {
+ {5356490725342733, 4068788685039808, 6047372383097019, 3426510449207690, 4705728718095123},
+ {3007896024559801, 1721699973539148, 2510565115413133, 1390588532210644, 1212530909934781},
+ {1205281565824323, 22430498399418, 992947814485516, 1392458699738672, 688441466734558},
+ },
+ {
+ {3538981275120648, 2874522279215958, 5384551777942367, 2992835507144444, 4815164902360267},
+ {3302427242100220, 1955849529137134, 2171162376368357, 2343545681983462, 447733118757825},
+ {1003649078149734, 545233927396469, 1849786171789880, 1318943684880434, 280345687170552},
+ },
+ {
+ {3979319739304371, 3173810108641712, 3480574285526200, 3800294424979384, 3983333585686372},
+ {2754253003222887, 2275532945921888, 3105484814506120, 2795714951112672, 3618146930096140},
+ {247596824353536, 285396193673154, 686289557053653, 399468081949262, 249109087231255},
+ },
+ {
+ {2723125664053674, 3464927193948491, 5445834280101391, 5612124161635761, 2933099654237696},
+ {2672303537844268, 2038791134455123, 3285678115022383, 2900519586434405, 1978453542160588},
+ {1705147526637648, 1274613803517124, 1602845665731412, 1064073198174681, 1486788069078519},
+ },
+ {
+ {4077390367222227, 3800932136610666, 4160144924974108, 3561238039866711, 5997919559096945},
+ {819031393505739, 2088275424107290, 1796234646803442, 1388708737598893, 2937136216710939},
+ {944757498200715, 2015594302768299, 813220261760372, 867002775164821, 501734915431717},
+ },
+ {
+ {4424498381651951, 4370145165962473, 4303795913232316, 4673352990886468, 3539252307041619},
+ {4258052207216187, 3760480385682185, 3206156011228824, 4088908699869294, 3011569459811111},
+ {1187304510804619, 1384816718516187, 514455602674227, 392638325371554, 588228521113051},
+ },
+ {
+ {4219797873858933, 4958627631706417, 4511020049341415, 3218925652522905, 5097166154822735},
+ {2789655568104153, 4038602698967181, 1701909246528643, 2824012136983963, 2400715389506309},
+ {1130277769648576, 1946206888578836, 1343266549795147, 2083590873042325, 264064594409097},
+ },
+ {
+ {3196954689864360, 3706526534080788, 3004981697061754, 5970179548131185, 5036616655131901},
+ {1526130015031824, 3071067159569878, 2312643039801922, 2400491084238785, 2092334718179931},
+ {1720808849496600, 410920656934828, 864594478015792, 229141760159822, 2037677155881017},
+ },
+ {
+ {5749040666310109, 2431937887261040, 3580364244969437, 4752008191428386, 4786853370158738},
+ {1789863266178839, 2202012677135000, 2680121806416879, 1722812656485926, 572531509973556},
+ {2175782751601278, 1608407337873936, 816706054544173, 258225706360159, 1478818623198000},
+ },
+ },
+ }
+
+ @(private,rodata)
+ Gen_Multiply_Table_edwards25519_hi := [32]Basepoint_Multiply_Table {
+ {
+ {
+ {4593529082752461, 4913481494458327, 5105340091484689, 3450213179198615, 5857240422918567},
+ {1412482364088803, 4062389850048069, 923779398567547, 2023841154802081, 2607705760638543},
+ {1825728698698411, 497946242397168, 105715611816086, 968568072676853, 592999326381074},
+ },
+ {
+ {4495184218325789, 5289073944532264, 4218636788579151, 4988461406676953, 4686478434934441},
+ {2949190053601679, 1979948019919136, 2471186112468189, 3573963359061221, 2216896082446061},
+ {743917567567859, 870447381138646, 392196079309387, 1786878704882853, 1520161635991866},
+ },
+ {
+ {4744444857419634, 3144662423000833, 2994206879871174, 4901643262699391, 4923693546628412},
+ {3089537977529994, 1888948267748045, 1789290739253972, 2597750135306899, 3142762081370390},
+ {1764333363430455, 898309455329908, 1381444383468949, 620561614151766, 158377983927494},
+ },
+ {
+ {5941345963042037, 3413323930288462, 5115763723871020, 3248416926384114, 5473315945632476},
+ {2269111888817457, 3231588657429924, 3123230781695332, 1299656894822778, 1180051671372258},
+ {407953783981, 1647278360877740, 584504284208188, 906066565536232, 1341016264992694},
+ },
+ {
+ {2432346762050178, 4412970725632038, 3922648159237080, 3005442494216723, 4442116552336937},
+ {2381425302937802, 1387820520945502, 3125986768243210, 2463732477189113, 4185413214185067},
+ {286790540720370, 376171092666609, 1535083117539001, 143466475958698, 1595136426572043},
+ },
+ {
+ {4277560779811042, 4605632954767560, 4619246140475080, 3484505719110307, 4989421629835765},
+ {2829089547178292, 1790256014216198, 1797656649279268, 2562891052522691, 493980515519391},
+ {62004126799683, 1668357417723485, 402010966421038, 827662362499868, 620754241677270},
+ },
+ {
+ {3919396572999125, 3838658814915336, 3750839246192093, 3726674239012627, 3831212626851778},
+ {1227888687423439, 2913177985394946, 2412294236854021, 2805130984485539, 1308360976872086},
+ {1643929373822818, 59659873139317, 1165353313134798, 2003225793255085, 1953102130608543},
+ },
+ {
+ {4114999970343247, 3274056679568382, 3954123294817179, 3769263204026901, 4245068682986802},
+ {898618711827587, 1314215296781160, 1302503840208753, 3496738988099889, 1698289814254750},
+ {1392999845620760, 634309693840701, 815492400002072, 340703897996290, 2038693787178716},
+ },
+ {
+ {5214250944985254, 5214298257940112, 3933846341585754, 5894386249523842, 5770685254784336},
+ {1934541077562988, 2222946897208970, 2251242179056732, 1591285457544104, 2747813687509638},
+ {1016675746743198, 874873189324170, 1360411561434916, 1581878592793672, 1548505102984557},
+ },
+ {
+ {4769452847684060, 4913417142027999, 4139599914472574, 5727971436547121, 5162246544117082},
+ {2615904366263746, 737197398316645, 1602932940462504, 2167985252180769, 2559960808783062},
+ {1882565165016312, 1581434850744420, 1900290919378503, 1985953844470085, 2168995994538833},
+ },
+ {
+ {4554120491153816, 4069860035617982, 4340413640826432, 3211862620694644, 5818608637282174},
+ {1544885394173400, 1572082853154176, 1022098019061266, 2766927411109582, 2094149897716596},
+ {1565161503379169, 1009067677698409, 1758464151571027, 1604769367828030, 1207412426608003},
+ },
+ {
+ {4015717287484591, 5253478309058146, 4070204443357591, 4445835852409645, 4665111518123177},
+ {2854833619490147, 3573568625503236, 536183518454769, 2263990573554737, 4044861757799243},
+ {1398840935273285, 790488576331737, 33415624257391, 1637374533896247, 2205752015162110},
+ },
+ {
+ {4260625486568009, 4637770924690903, 6480430642402074, 5542751059832424, 5622960391176990},
+ {3715812780985479, 1012232238437221, 2466752896497024, 2611001871592954, 2143269004082900},
+ {1886046851462393, 702395341735300, 737389004224425, 943477665979721, 723064819201181},
+ },
+ {
+ {5226062982149706, 4477280967632100, 3095356746333787, 4567645348066962, 4846495995079660},
+ {2444351104229624, 212638631228834, 2148034812459853, 1041500100514044, 3853826660522166},
+ {273084620529389, 1358348733025497, 1143735162114047, 1683813303234668, 2163735276562013},
+ },
+ {
+ {5320556456798805, 4779694419891170, 4876824494496501, 5903452387913251, 4729985500450036},
+ {3477960290395163, 2468183980355970, 2936794001231177, 2308108181814059, 1969019168758558},
+ {2160310767797410, 344164523453241, 83129919763985, 1315117733435601, 945559910324390},
+ },
+ },
+ {
+ {
+ {4363327446469061, 2701839972520523, 6527685309871122, 4056456213766895, 3880569128224647},
+ {423177393665983, 2333545232306939, 2028971153113312, 2728157354019203, 3777730507929771},
+ {1435691822393684, 1850026012837208, 2218717487026642, 81859254010196, 244808221751742},
+ },
+ {
+ {4151019106002309, 4804743010530635, 3757223421954400, 4766036153424381, 6107544569595961},
+ {821837003520359, 4010299059749559, 2863227431802226, 4078726431091997, 2442551264358059},
+ {1428688544729295, 109069749881410, 270830364539996, 1755181768867140, 162349670944771},
+ },
+ {
+ {4642027397896088, 5510058210884768, 4553756231196669, 5068441159437344, 6370925538331183},
+ {2639121586131590, 2408957406336796, 3986248100020063, 2989795052558558, 2164082093074357},
+ {309881142350067, 2106019349943259, 816133263871674, 2018031260992166, 1563425406132832},
+ },
+ {
+ {4395494918929745, 3011447404605211, 3917145931603942, 2759967153620848, 6379442527779295},
+ {1498799085180043, 1744340656397133, 2064851197592072, 2429833814776112, 2145324400616903},
+ {614788980313577, 1501513053451003, 1472055221710495, 1920317897819127, 2208964791748263},
+ },
+ {
+ {3560784093342680, 4994362478801752, 3255476397621627, 4445556105981925, 4954471675599246},
+ {2150595732685700, 3115920468099904, 1640951315905191, 3465930332728019, 2707896919197916},
+ {612249867445962, 159208429955777, 563950177277347, 561041393363217, 1270750549218661},
+ },
+ {
+ {4520180469529123, 3948074172686157, 4376189225516076, 4643310756673520, 5392469157863016},
+ {2055033216205027, 2461832572574425, 2742691255886072, 1052243367900374, 2752099767668600},
+ {1827261746419924, 1468053133723229, 425022050209163, 1161272199376693, 589189496874922},
+ },
+ {
+ {4438522896195229, 5675329383977909, 4882438618733149, 5825827678555036, 4497535703422370},
+ {2005207463235253, 2001528853385595, 1602253387656095, 3101879903751894, 2375325873201006},
+ {847469444462207, 318959830531389, 408429171873782, 1661514071773102, 909441091898553},
+ },
+ {
+ {4102243665939998, 4215863334856383, 4408378320450327, 4622977479151665, 4039328475229204},
+ {2174491994328136, 493557282042709, 3602705188549813, 3249913558677235, 2748481399349512},
+ {758760864397232, 1830650226770835, 326981597370189, 1345979301472296, 174985669849506},
+ },
+ {
+ {3114038058163888, 4115257910705954, 5304962337604028, 4942520420915651, 4570979005352829},
+ {1616868525778916, 2685769941228860, 1500533033491414, 2505164168102999, 2558430770009979},
+ {2210398167996316, 2029125611734957, 1527318329127090, 226535237621728, 757747276478551},
+ },
+ {
+ {5660830910412470, 4039716640180729, 3468207460119772, 4614076381392168, 2442548670982292},
+ {2039774403824382, 3183946537620297, 1982095153858182, 1293586830098836, 2438708503064038},
+ {1357360519318812, 2045548381976834, 1766860667272665, 994521972889149, 393185631961961},
+ },
+ {
+ {6365035791876788, 3957527440519852, 4079038689927398, 4319831229004816, 3943934873019078},
+ {2354388502926730, 2133757859975250, 3747940319461896, 1050624714408746, 3528225787559372},
+ {1423510913950154, 1407788039482417, 761922275972375, 1783557942644647, 464730646959110},
+ },
+ {
+ {5146524748212414, 5035960985653238, 5028883959266913, 3282581313444735, 3905335483972979},
+ {950694750709616, 2909132113066654, 2692353349246129, 2659905077175497, 978201784181073},
+ {1078796318026741, 2070782433025097, 1700702188087909, 1447652546515478, 2144027848464236},
+ },
+ {
+ {4464099897473286, 3120477039861599, 5276369827125764, 3567131403687606, 4968190256098962},
+ {4085811716920468, 2616309657099343, 775638006452370, 3253232221169984, 2587485588949578},
+ {1012423034220617, 2045371869775344, 1260737445157584, 1833095526522043, 1066294173319533},
+ },
+ {
+ {5773192417487042, 4517701999097386, 4655557572427803, 5616698382540752, 3371552871839388},
+ {2877566362774786, 4401330265553408, 3208625757371899, 1399785720487456, 2531340752609210},
+ {1640471888126382, 1014801052117284, 1178704129888297, 982929852576812, 981292318502343},
+ },
+ {
+ {6476452238344334, 4693003674971858, 5211751500997938, 4121351294551163, 3152533251509898},
+ {2011936343019114, 1133486795463590, 2647435457385352, 2628952425675517, 2374701464984626},
+ {1245374341789768, 946202302464214, 1370924353088231, 682015131982855, 1275473548530510},
+ },
+ },
+ {
+ {
+ {4235275101318885, 4886666925763093, 3781172458925008, 4774837350787537, 4519905633498379},
+ {4159636855200485, 3150221611558687, 1363421772307006, 4120947913313657, 252053503603381},
+ {45902352975738, 1246446699820833, 173320410042641, 1542230462600972, 692910725375140},
+ },
+ {
+ {4486356754653352, 5011982731057698, 2800477110646540, 4053556040992402, 5267180761554575},
+ {710084928405448, 2105676789486896, 2420643007484910, 2605134634368896, 3302669631199693},
+ {2191680341805656, 1972509245077282, 981795995975654, 852454486043614, 1189735660434765},
+ },
+ {
+ {4897930998338676, 4879106310620971, 4682586750207620, 6132197307461033, 4233426591406375},
+ {3995777047683048, 3833719910688599, 2444044754441170, 2232313400412571, 1420975603500953},
+ {1931343025077052, 1393738210614177, 622857924319466, 1123524882306454, 1963513295012502},
+ },
+ {
+ {4596722267439639, 4583990247552416, 3156713638372258, 5382313953040853, 4261038954366871},
+ {1850504730697909, 4381679472853618, 2011448898092860, 2090154061858281, 1857166627539261},
+ {1509035496076582, 1583601071466027, 421912810565136, 1678479534084506, 2033502297510813},
+ },
+ {
+ {5152283091655165, 5421718026722430, 3997156174417042, 5001987993936945, 4470112047504242},
+ {2238137325796915, 1165391281982950, 2048774700033766, 1309041739154703, 3204681887791132},
+ {520151332809519, 1588829471961614, 2166353389460390, 404024831468766, 1335244071323823},
+ },
+ {
+ {4644249663336450, 4507701753581319, 3592182426303562, 3683130545837732, 4598992005732335},
+ {2528474489315892, 2071299735249833, 2619224970187272, 3271465188079442, 1519932762444249},
+ {1935180256227856, 250757393177447, 1959439731378182, 1297506762666169, 575184640324100},
+ },
+ {
+ {3998007896814392, 4789639746579090, 5427007329099910, 5561733860472916, 4408133776555178},
+ {3563813919863414, 1486712601904120, 2979081810490774, 1807789883906314, 3546555493967378},
+ {1438068615152094, 34949160848567, 1911746456436447, 1412684293826264, 1046374507505090},
+ },
+ {
+ {3358198622960838, 3580145032458308, 6285906454262483, 4413045221104222, 5178477068028319},
+ {1493476678908308, 3319155065445914, 2088667670293411, 3599225826407670, 3126758502479837},
+ {1428599160764785, 602821281250279, 1877258833313507, 333285098655770, 740310036947361},
+ },
+ {
+ {4437738381533964, 4511430215080912, 4623800711093479, 3858159170572748, 3792114250503483},
+ {2569231089452712, 3770152139328302, 3269539085929031, 2383025095054982, 2248498609425137},
+ {375535123602711, 924645774628115, 2045840727994073, 766250909414083, 1069698092749769},
+ },
+ {
+ {4435294130703604, 4934879817377642, 3598080452693711, 4396369088299832, 6194434176750643},
+ {3899859044211942, 3058237431324156, 1669265990252613, 3808823766704698, 1861135005644935},
+ {1352954153117419, 632457759471481, 85028188501619, 1852310027888311, 1569233778435479},
+ },
+ {
+ {4994607739226691, 3549890051462689, 4602469939135293, 5262974664864567, 5829540047772287},
+ {1177033227220429, 1414982090591775, 1722841418062421, 3232176376002923, 1625133154241833},
+ {478074309368979, 623121553345246, 885068774570210, 117698677138481, 109006840646140},
+ },
+ {
+ {3228583777446740, 3685494966163883, 3859895584510878, 4132565491795209, 3602518465644145},
+ {1476961150268616, 2321154243603617, 737795879830106, 3409730959236147, 2062873179003703},
+ {1329749333731727, 46254713998516, 373767480531871, 1933047124368118, 430092326122748},
+ },
+ {
+ {4068619402415723, 3955796447715502, 3724578346370833, 4337532310052478, 4252452058492903},
+ {2483442550312325, 3615812911108800, 2858427288312835, 2135393495237610, 596254727540093},
+ {8959488931169, 1768025271694380, 2157573235225770, 292082063715064, 330646837880843},
+ },
+ {
+ {5129020796146722, 5575913156701592, 4643684154507286, 5052753294034768, 4627882199658166},
+ {1682783588724042, 2651474877391040, 965357158907406, 1910483514645702, 1644451034905796},
+ {976078747227308, 1952905065031031, 949292862704054, 1492592732072346, 1010921457352162},
+ },
+ {
+ {4006410514827696, 4367363852356865, 3108174070644550, 3399842446392251, 3651405461962036},
+ {2963842949036336, 1110443523197923, 2370466150687958, 2051405852060769, 1998735788124574},
+ {629291283140720, 1484410172308977, 1230690465849055, 1563468011476927, 1425159147311735},
+ },
+ },
+ {
+ {
+ {5585239563455525, 4610636723895044, 5486382712767880, 5982393863492935, 4225244847092674},
+ {2874785617528993, 1037465406252872, 3296887051144680, 2286839599744315, 786748793374778},
+ {1152063960223905, 1495207756023516, 403624329924470, 288757773501508, 634701074033280},
+ },
+ {
+ {4288607522123402, 4846896146524989, 4707359298406332, 5135207568875886, 3789334229842457},
+ {2917883701302634, 2925085599109681, 4014710226846848, 912132719741982, 2714081319314151},
+ {204576686258175, 1916354881141604, 2182213405559566, 836541881049164, 1393662576855498},
+ },
+ {
+ {5759444997810940, 4193440837630205, 2993247029494710, 4574723038696780, 5462384317223070},
+ {1429326167011008, 3849536799125309, 2267296904452424, 3653618160132546, 2008400870233860},
+ {1583200791922713, 581155064879634, 776749520692821, 82151283071376, 1733847968592305},
+ },
+ {
+ {5824219020582313, 4082583579489045, 5236716515955319, 4695754388607834, 4087929633004663},
+ {2723457493421297, 2288104271131495, 1889807602666693, 571526543144584, 2151183507738315},
+ {216379584390389, 359329711860756, 2220840445637019, 1935487238453911, 314381139238943},
+ },
+ {
+ {6324432942393073, 3866303010803999, 3020114267775140, 4943018510078408, 2696166744880915},
+ {2134908988986295, 2962507202980067, 1681144354786142, 1678261855220080, 2165079891714277},
+ {839191618399610, 151822034158330, 65272611705697, 938153274860627, 14360318777459},
+ },
+ {
+ {3118414549517527, 4750668024533744, 4389573074356623, 3687569756425714, 5338903547055573},
+ {1473478682616257, 3633382583874766, 1909784146543313, 3349986706799106, 993668408613515},
+ {364270308207016, 667227739516977, 122427551474936, 957177061876827, 1110258403339423},
+ },
+ {
+ {4256211953323020, 5655880769308112, 5147711084133693, 3515346496193909, 3997285326966523},
+ {3727619641010474, 1181551732606964, 2600588673325403, 2469054944509579, 3385365618247725},
+ {858909692206820, 61057235030988, 1105898533486092, 2202030785898301, 1422234761465688},
+ },
+ {
+ {4566369519147140, 3936942479708331, 4946651352770194, 5597737572220025, 4038789996699983},
+ {1354120322856538, 3567014996875285, 3125649205892726, 3221576024570935, 3804405204938131},
+ {758252632702114, 914226082256766, 434171717412081, 779505540917105, 51590353584795},
+ },
+ {
+ {4416135541622855, 4651530410104026, 3833614791957416, 6714310821280595, 6038964345007539},
+ {3122819969959355, 1154192626573742, 3197914057178582, 2213609121110881, 2415518693959367},
+ {1900133378602138, 577297894556411, 1975904780443420, 367702995667978, 971695605371773},
+ },
+ {
+ {5691739211507754, 3947360890016266, 6002902486092077, 2925962297163746, 4016189592321792},
+ {1294948213915982, 1859247234048810, 2826079115120605, 2717796469093276, 1254328736376524},
+ {1309911522909577, 1419436642934017, 1066858837800204, 1932820656369018, 1183788306261091},
+ },
+ {
+ {4373293771099146, 6029412334349101, 4603988300239160, 2779063318785645, 3538182001391078},
+ {354784062716014, 2960996156215287, 737478213901140, 2448765213738437, 2443710778345986},
+ {37327849111839, 283459044945755, 353933224898901, 1645288254358965, 1295375429334450},
+ },
+ {
+ {3677292170794769, 3117650463171591, 4719239493455234, 4362161261080430, 5717636534074846},
+ {2663608264759869, 2105855808111831, 3795920549032608, 3588992239888494, 2806554331792318},
+ {2036310356419974, 1862941437683537, 2122628002305950, 427826430955887, 291402007632220},
+ },
+ {
+ {3100956993836596, 4149163064979557, 5785693523916593, 4751072583726928, 3316412298207139},
+ {2400585099524078, 845178406557315, 1712123121349035, 1518690883002826, 2049951197688491},
+ {1805653877101595, 2041224626272278, 851063029095866, 1497753468187708, 1406228898239886},
+ },
+ {
+ {5260996583106547, 4838608075273405, 5366327117123850, 4982440029922063, 5698050109664171},
+ {3676073115087797, 2883668558141193, 2503071760256012, 1640618939206309, 3001604944016599},
+ {463897193543924, 852129647033757, 2185610432355774, 914719594057928, 342067349817283},
+ },
+ {
+ {3765905247379871, 6338723143452534, 4484328730824797, 5536719681008311, 2764639921823257},
+ {1030797243840613, 2110720517661432, 1415230398470209, 2977956931886379, 1982287306571007},
+ {2180738906930659, 1806951067450075, 36005005692651, 303238055099928, 190139573853343},
+ },
+ },
+ {
+ {
+ {4025496086329564, 5028184343166740, 4304607245262868, 5977861543210978, 5975943712754890},
+ {1773953341907106, 1826809791300708, 924874532383668, 2964289914628984, 3000051694532148},
+ {1048828262296911, 626018299495748, 1536855937015065, 557005099579827, 205000143299648},
+ },
+ {
+ {3686649646834702, 3431735540864864, 3540678075266127, 4755119958422340, 4426577953698517},
+ {941815577996700, 1930911276112812, 3001621068228165, 1967675522206374, 892948220720651},
+ {39364207708032, 54077643340559, 47072300438335, 484490203728205, 330170579231628},
+ },
+ {
+ {4702834568738627, 3291678731018536, 5642230899808367, 3758646432111623, 5155137589229851},
+ {1020447780607279, 2803044870250806, 1618835409581889, 2925650123847541, 2605959132875331},
+ {1190283817822151, 29815862110548, 1401771831527381, 1814017508050437, 751331585591881},
+ },
+ {
+ {5109595606310342, 4551817631663576, 4964640045962167, 2568185324125768, 6484076393091613},
+ {2159866514586362, 1758376548473728, 1635569740383557, 2443910752037966, 2023235829583533},
+ {535848012622913, 543536404720769, 149076814975879, 1567757637416350, 1002851193383852},
+ },
+ {
+ {3815561875504886, 4987304354260221, 4882489851059671, 5118054256243381, 4641807084989976},
+ {850247344591352, 3894610597706487, 1974409276090169, 1605973976114297, 3601811238228268},
+ {66796032196982, 83108349878636, 1058512765854606, 355785880766958, 2173660513649027},
+ },
+ {
+ {5137434473036957, 5769675136285847, 5436511544403722, 4264839407576387, 4266175067727596},
+ {1941123290917747, 2316977311376991, 2913763383192580, 1172954226263395, 1951085968954154},
+ {1331723279107642, 360406964548232, 602431788387748, 1292398959539176, 347247628588850},
+ },
+ {
+ {5432516922132898, 3078886318864995, 4583513191179486, 5867019372106709, 3411264839291911},
+ {2170226002806030, 1739335733478471, 4017472424997012, 2918660155665329, 2793865679796361},
+ {245885669910192, 255454579697350, 869246923980317, 823008017430135, 2047987637517532},
+ },
+ {
+ {4988197221931747, 4124266159815332, 4025663002514467, 4403069876409057, 2825978174946111},
+ {3615548446949869, 2386240595324376, 1969460953567929, 2939417927358269, 1831662708850445},
+ {1325588019367749, 1763566216507756, 445592400440775, 1009027711126237, 1471076108623188},
+ },
+ {
+ {3535455324868691, 4187842716980314, 6000482158112321, 3740505414106560, 5271856051582847},
+ {1181816564414671, 1156678021972118, 2682384137206273, 2260248858296388, 1100324256765571},
+ {1487590095774723, 277659353917859, 1381509894936782, 1061130669028904, 1364761503808628},
+ },
+ {
+ {4778189969823672, 4001451898457449, 6113563635354943, 3279804336055010, 3551539211588960},
+ {3358253142401746, 2070882729090991, 2076758122179069, 2612730216279296, 2875157527961954},
+ {1082784010061460, 1534894036268453, 1852407202514802, 2109696474131863, 1530718911157644},
+ },
+ {
+ {4923904010378051, 4401333064112293, 4345896142363128, 4462036896398403, 4199434117360330},
+ {3404425764066199, 790431937118435, 2117892820897492, 1747418170252123, 2322149428381644},
+ {1548552607325007, 2020524571521392, 198565314654983, 490668591018400, 531050967405176},
+ },
+ {
+ {5145969570912646, 3496492300608685, 4069590843971303, 4335556955800239, 3325377629546533},
+ {2623126033999932, 3437252355580701, 1673392257908819, 1954440682865467, 2560737733895255},
+ {516406018439380, 1624367135427190, 1319745729116992, 1076628515910554, 819495581575694},
+ },
+ {
+ {4005978810673255, 3160053273427578, 4474659303213566, 4173935427495701, 5201857712754300},
+ {843136030895887, 1929944939303616, 884551308418834, 1356687291240061, 2259204804361506},
+ {1461715846997541, 2038281458208083, 2119767535863762, 636224052565171, 1712721429371389},
+ },
+ {
+ {4975731433879692, 3888553624589664, 5228917373823987, 5038386998880250, 4707655682255612},
+ {3409114563124612, 1820064381354618, 2421007346773091, 3239920960596314, 3726969650504610},
+ {475869807928836, 887669112822100, 481835223948027, 1468799954696850, 1370247723645687},
+ },
+ {
+ {5954383345631578, 3742995524386402, 3611065523713845, 4447231480190211, 4725820376570018},
+ {1943063487159002, 2890245371286974, 2837035330843453, 1080549927676027, 867285909606140},
+ {1413582027032622, 1273926892909999, 726179076119442, 699229594605794, 406422835715518},
+ },
+ },
+ {
+ {
+ {4513888950241631, 3212738446973608, 4558390526464820, 4859080230791315, 5273416148656656},
+ {1326059070986753, 1683859889439034, 3052200172327874, 3805600625804475, 3687690452819464},
+ {1081752225631401, 201284952113932, 1619339403526661, 1533363030164674, 1727571790703503},
+ },
+ {
+ {4206177554516483, 5468031785191800, 5978090949319557, 4899439545685678, 3929672195094815},
+ {3151535789445747, 1741766716299828, 1742063303545331, 2027626928190420, 2245203856982753},
+ {868012933261061, 1472665613225898, 1744063644616181, 1350305502884983, 2227467074628670},
+ },
+ {
+ {4669057309967741, 5650515638764201, 3042033906165361, 4078124455841206, 5666341739515191},
+ {3587030559572189, 2850528363281919, 2974216851298661, 3227895056003248, 1349661756105253},
+ {1313383948772993, 1074655824143287, 20040386640896, 305794891855170, 2123092901229151},
+ },
+ {
+ {4199945629383318, 3594320984526977, 4229880092041671, 6384664478996443, 4732837782434517},
+ {2744443256254860, 1013874505344583, 1972732629285783, 1936827407065469, 1830481951704579},
+ {634737804354539, 422989080575800, 1774993942417585, 688011718282303, 581542014403477},
+ },
+ {
+ {2816888940207091, 3903781507184007, 3616069829367681, 5525450216549915, 3780846206608878},
+ {2517199667227667, 856367096857961, 2630571629218547, 1768604592283813, 3688963458794126},
+ {1683677903016217, 2036167240589310, 262287609979509, 977873833112269, 433284640623898},
+ },
+ {
+ {5477402921384451, 3117269161199628, 6049837891653338, 6034999812243824, 5356551064760510},
+ {1755760392036121, 2130115351478138, 2694425247498002, 2043622709923142, 2338295058055586},
+ {1425112218383847, 329346717672590, 378517748485393, 1806152114945447, 1211275024279312},
+ },
+ {
+ {3594715588472482, 3844045487620198, 4484578538777484, 3113667148844230, 4337495224693479},
+ {1968587687914188, 2881021730370090, 1429009633828432, 2770076641127580, 2012343565772575},
+ {1629969809602186, 1106234784906336, 863587490378700, 1792807263239898, 1429043938024750},
+ },
+ {
+ {5737804770941067, 5078013196347608, 3898224610791405, 4804530531188967, 3180800540121608},
+ {1973106012015851, 2593923400059844, 833516958919695, 2182197879897069, 1721403407106648},
+ {1591076166555979, 849361769125080, 1443799738863429, 166584794343739, 1861773413238536},
+ },
+ {
+ {5730227718465208, 5596273386383722, 4195854427433762, 4069266668520101, 4524280540784068},
+ {1968981310480276, 1950975116204498, 2592307802896060, 3813918534870745, 2620661073133464},
+ {936764653391291, 1452448249608980, 1312847510424692, 1846051928374105, 531372961271999},
+ },
+ {
+ {5549943196407418, 3432818760073271, 3449244033859606, 5283577488399029, 4864604608008479},
+ {1733819728686816, 2936024966547233, 1590816041651632, 3163811004299109, 2676757470677367},
+ {1319097278964637, 787422552977413, 1599496421811883, 1959379193761008, 1506646670818903},
+ },
+ {
+ {4227254412838170, 4548570321204425, 4285644009760393, 3751016940211786, 4098838617641914},
+ {1732471582908700, 1866076266304485, 2819215151172481, 3074745073420508, 2774887501545996},
+ {717261628309176, 1858796230699344, 551077134877547, 149402535309098, 2105648961714394},
+ },
+ {
+ {3871916223505114, 4749816457502813, 5358561311326743, 4112663885073414, 4137415642080692},
+ {1127279535151728, 1199265744257977, 1248562495202825, 1868357952639788, 917052103965266},
+ {25664888255034, 1628004430886188, 1439984389498414, 1961957176184883, 182596205772698},
+ },
+ {
+ {4179077756813138, 5647690538147405, 3274850245594335, 4319226212135161, 3864148139899748},
+ {1739387701061410, 3112148637704823, 3028846916651989, 3700388643798173, 2412185850016002},
+ {975143220058337, 825243809988211, 515186464897625, 1179464291552333, 2112614471328036},
+ },
+ {
+ {4947873049161087, 4901033700427489, 6675583808729484, 4941667050946228, 3120269525234559},
+ {2996598747660015, 449189546044795, 2197501482114022, 3158206489499126, 2705800926920583},
+ {96737353895103, 1534044505139178, 563303281603459, 407703386650348, 1821870774469537},
+ },
+ {
+ {5049500432849751, 6040441932911013, 5618655093441099, 5061587505104794, 3837175101097290},
+ {2654088892951999, 2871006956063187, 1742690076584393, 921899537851044, 1870021525725886},
+ {1637444308641066, 1472124432669136, 741811397216072, 1252880060061292, 423564866101658},
+ },
+ },
+ {
+ {
+ {4796818337004571, 6222611117014093, 3083419469630983, 3862822099971652, 6509664209117283},
+ {1171837083014025, 2516532715963947, 1770010974323603, 2517908022038722, 2020794083615321},
+ {762321251771152, 1460210191529427, 2248797163104578, 217468651569622, 63003536153574},
+ },
+ {
+ {4259858178043342, 5554955317979561, 3911791110113593, 5525892988208900, 5545696994818748},
+ {391588043113892, 2202456919563943, 3869688632614537, 2945959779196464, 2143606811138354},
+ {719793864170869, 1411477466905009, 1515019021063010, 1483421690183889, 1704042941619334},
+ },
+ {
+ {3034963268199750, 5870224135513779, 4115305817554936, 5421579290342892, 3835694901998808},
+ {2769635787032504, 2958323523618463, 1537480429839772, 1483278086593314, 1378968978067758},
+ {1315034452637574, 1172434640681242, 1135533609020364, 253349230877293, 161211572823476},
+ },
+ {
+ {3942650253210285, 3918824117103583, 4001647299508483, 5240554545879312, 5035373070605317},
+ {2659408003097885, 2049444491227493, 2594690944032877, 3421228755254048, 848234126951057},
+ {437225545901468, 888271756229202, 903344393515123, 162913205438885, 1475178706291532},
+ },
+ {
+ {4287921885063088, 5041248821201299, 5585484729625036, 5534367719396511, 4532272822475758},
+ {3707293450173872, 751219268219695, 1525065253586106, 2054680090861517, 1393874745922970},
+ {1910711495320594, 321017884248758, 1651671690842787, 527123817162741, 847944616444202},
+ },
+ {
+ {3415231495445846, 4190597015532201, 4905073239386883, 4940927269911495, 5980840029199164},
+ {1474221667712446, 3068688770339565, 1358088375247373, 1853329794010803, 2931295009606082},
+ {70084211861389, 1248863300280704, 1009402227613886, 1445171656255193, 728732085908498},
+ },
+ {
+ {3340501878764401, 5410923356778271, 6030788584012822, 5594611759355304, 5267577702264329},
+ {2869750492870027, 1153392601340917, 2754776472841130, 1100510641818700, 2870221151280913},
+ {1481950048975238, 97096668186528, 429204027887699, 1510003697018425, 2114825823462494},
+ },
+ {
+ {5159850395392603, 5067743945456882, 4551909910661973, 4393814096795878, 6145580658249508},
+ {1440929316705129, 1633730452330828, 3657204567294737, 3657918436987822, 2561724546723194},
+ {809017030155597, 1831934834657405, 58189812416765, 1517873507099267, 889681994437792},
+ },
+ {
+ {4153444167566628, 4372997703941365, 4839161526733376, 2653398635504610, 5324373835991045},
+ {4007354401668216, 1201450641763461, 1526795422335006, 2273741230894754, 2130356372280991},
+ {1057020591512462, 1324094020999413, 655956927766596, 659874727272243, 2024954110083652},
+ },
+ {
+ {5839605326568475, 3831434019746100, 4883240784156331, 3880003889048305, 4841910074653809},
+ {2844236939823231, 3043783621566488, 3890227240890757, 3800769469380331, 3175183419371011},
+ {863608592350445, 1111828464904337, 322487356734403, 60843367779474, 775147863897458},
+ },
+ {
+ {4129677439236364, 4363616958764152, 3255333433286932, 4071265658640216, 5527560633207578},
+ {3501906805856088, 2995655036831742, 1989943322549290, 3334534687075832, 3371315397704424},
+ {471893887981193, 1459834432249674, 229072407724256, 1165980516905022, 1036865507138076},
+ },
+ {
+ {5587927329012785, 4196019533185475, 3488244055775669, 4788679066807545, 3936797203887245},
+ {2334971095120001, 1054095219722721, 1729452124624259, 3446754994849569, 3835890504040419},
+ {883720982539262, 2126174835830047, 1858128110066030, 1402309396930944, 1358212283922371},
+ },
+ {
+ {5437236132245684, 2619202868264644, 4266616048403094, 3779544081061673, 3472381895789909},
+ {1158559475833858, 2227035258871772, 2170552210791850, 1087363571520417, 2867304161007231},
+ {116357390237056, 38114324586368, 853586347213800, 1638943134635811, 1882124412005945},
+ },
+ {
+ {2871025108215057, 3893039278529517, 3878244260089116, 3893554424872522, 4708186328386966},
+ {1760242418163439, 3855738944127473, 2877581036561996, 3253911846338252, 671018190326366},
+ {1641735698439468, 1630160111859414, 1920036824528970, 346120100914920, 385076471695398},
+ },
+ {
+ {3934974918427731, 3807320560303621, 5860456491598573, 5199210868384009, 5781319959443384},
+ {819456425532597, 2215390016559513, 2301197053109143, 771274648900875, 1303516882225152},
+ {1530178090161037, 1646502716614548, 1058228190532635, 1522572712238470, 991147078780643},
+ },
+ },
+ {
+ {
+ {3763364100157977, 4436158450653533, 3664705850096563, 4592883978910063, 4855668048892712},
+ {3431442042489897, 3670457457720097, 2927483669898581, 2847896260114069, 3422237175305894},
+ {1907217462504765, 679044428705663, 1371479879514675, 1420793148384765, 190685345044087},
+ },
+ {
+ {5140896563326095, 4954544354938625, 5148671791011404, 4813313238272129, 4814788700593711},
+ {3528505813008031, 3913030166310689, 3457534787545946, 784019563379975, 1449546143149561},
+ {2213525665395526, 146358659614731, 1573034916169973, 1131167148341295, 1194403623212224},
+ },
+ {
+ {3034590507214084, 3771531416844161, 4279939895181473, 5778619660734332, 4308244183318381},
+ {2105305689409168, 1932040296635725, 2559301608776867, 1653053081843050, 3498476220207615},
+ {1916484225176, 1896106466807315, 1279953155660650, 1725386140841619, 757101416534772},
+ },
+ {
+ {6555214085737347, 2980588876755702, 4785845115539682, 4430693817238987, 4107141749770380},
+ {2133488547373079, 2884934342093682, 1652284377802152, 4287340267215791, 2741073463083472},
+ {655928016394658, 1087485647128905, 1281789693328119, 2088439151211398, 1863153332596984},
+ },
+ {
+ {5220143354789533, 4303392603719785, 3697665521216293, 5367115036779017, 3354674257103145},
+ {2461817469666051, 4062983661511151, 1323101412046937, 1360571080713195, 1716626899554003},
+ {1790273650925445, 2180187262630477, 28219260774301, 1951582862584504, 1059160821201578},
+ },
+ {
+ {3706860118974125, 6182298149062642, 3206841902738667, 4986080379139384, 3223876357324169},
+ {3108934357344473, 2823383892309930, 2709776767813967, 2732378265738840, 1695118712507849},
+ {95538772778706, 1914880923031197, 417513632407841, 1767845086605839, 832379724270193},
+ },
+ {
+ {5132941124964776, 4798553016886828, 4052101096460607, 4475816634870178, 3176602159556433},
+ {1456443406045738, 4161184975160682, 816382632051403, 3678387736600146, 2166890266198131},
+ {393110820654303, 662371396172458, 1370237312917823, 2034119121136113, 904928937827},
+ },
+ {
+ {5075422185081409, 4699433492834214, 5948286955155472, 5933498265459676, 6441657203628461},
+ {1257344135899307, 2776494249972420, 1637109398723534, 1801319038042246, 2082644998926031},
+ {189274223123103, 2188109173279445, 1461570511269332, 151886143484743, 1557837550414982},
+ },
+ {
+ {4365365818590957, 5180206223815189, 5035374537630803, 5955216889373899, 4177347431591518},
+ {4105224954841159, 3814048291702159, 1805828417935849, 1548444252518409, 3761242775865814},
+ {966697507230426, 1689614203301123, 867370120071235, 563108996765880, 1552869095947518},
+ },
+ {
+ {6190612622769392, 5262116783421509, 5770823033954832, 4892678801476142, 3789326136184388},
+ {2680510164419078, 3125272296703659, 2480535210869218, 464721098622880, 1141684153257222},
+ {1871952745325912, 144470913279784, 434631777342778, 552837449330893, 642852750438644},
+ },
+ {
+ {4755508755993467, 3653868693631672, 5880862524139354, 3244860344044728, 4481011039901531},
+ {1809358219650823, 2339660560948574, 2410584439137912, 1286742564054194, 3633419878206029},
+ {64765075641768, 68764899017819, 1968408548264810, 2037002115471749, 211556643344747},
+ },
+ {
+ {5543625841706618, 4560629261024327, 4731751483103768, 6307249547601622, 5012757099435702},
+ {3301009531661216, 2677459079264873, 2707326467220240, 2261655438430016, 2962646350850358},
+ {1579401584164790, 1951017356653076, 1801209077919862, 1153368800641031, 1775772413220140},
+ },
+ {
+ {3556317598507403, 5934251293404526, 4176527831714322, 5239968931380200, 4506603999756496},
+ {2798836099557035, 2002468979873228, 1132424890166086, 2388404451698808, 664387721246094},
+ {1947208168676528, 1750536949518976, 835780038339521, 1802624114603814, 1867663782159356},
+ },
+ {
+ {5351331441108046, 4901733280572801, 5434846723443585, 4372148225205494, 4376250516119689},
+ {2519667781375866, 1132412577764719, 2322930879998983, 1660817657158452, 2806576583179867},
+ {1273923691469553, 1862566872300733, 2236121435313308, 274949363314112, 477088969758259},
+ },
+ {
+ {3358480296518006, 3814827118577810, 5033804317047304, 4803399909431456, 4940637069622359},
+ {1965761504739774, 3200209926214852, 3722168784530754, 3464219522306102, 1953662369491229},
+ {1946412430894973, 2031215026716789, 1150845535883051, 749273986980949, 1433091314912259},
+ },
+ },
+ {
+ {
+ {4565135018699993, 4952235844716789, 4332776238462736, 3944983589420527, 3534528668424353},
+ {875483311206731, 1070293195031859, 1281389774974538, 2234860500431395, 3030484939064537},
+ {2191861413872447, 1998107865473216, 135161483760725, 1133778951112075, 2177808149908975},
+ },
+ {
+ {4472607877838387, 4680291079417999, 5266381476904463, 5448529984859500, 6037873358663623},
+ {1355285592679599, 3216332013847453, 2858567121370219, 2432376038574376, 2734263724238645},
+ {449706520184472, 2214233011551797, 684523848529734, 431843026966950, 1758835924810462},
+ },
+ {
+ {3413242279346498, 4524603375434282, 2637627437993422, 4373910262118552, 5420094068912965},
+ {1617166089281188, 448710947316786, 2017034644293574, 1886691422085664, 2375442150405559},
+ {1239614751060180, 254449956067847, 1915952567259905, 391989559805324, 853553448301328},
+ },
+ {
+ {4142542119790983, 4675453183245373, 3888287250251838, 5522078723840086, 5552692716915124},
+ {1381495390544381, 584763141985101, 3131504846670548, 2565162572339012, 2037973653370614},
+ {762375715838646, 553562190209386, 1146347552263484, 824188464596685, 1830942666102590},
+ },
+ {
+ {5823375217862555, 4240127004291848, 4611065015006224, 3518908128296096, 4915429068500234},
+ {1348374701112873, 3953700554194482, 3402331094627540, 2804779645909956, 2204826476892034},
+ {2119092558617159, 1045482671389213, 690197889240825, 471826136635342, 1637923217880356},
+ },
+ {
+ {4059066650158007, 5141565698162354, 3733026015817812, 4875063676054927, 2832005231346927},
+ {2181081937454965, 1121830291087960, 2832579231299976, 3124836269482413, 2225668708158199},
+ {1193994157146400, 1628108083694642, 1021885296427132, 816068909639879, 2088480068848711},
+ },
+ {
+ {3180618525607636, 5342429333917474, 5008239417572170, 3506064373977331, 4538653079573275},
+ {1673050054377632, 1765054067091528, 2962973405879830, 2339273872052899, 3950931503569149},
+ {2229241184614921, 2107352800266199, 77312115078922, 2151892262530718, 947910914861383},
+ },
+ {
+ {5320544374459840, 4141095319362425, 3313360370605015, 5185507100540960, 3283266576250376},
+ {1528297312537716, 2187935649407647, 2967731417391411, 3155021192657576, 1577434241618944},
+ {1385713524190245, 153942078459639, 747467190641094, 1446053675113471, 429215290527338},
+ },
+ {
+ {4130033413775598, 5253437474448919, 5186743122906330, 3072446418934431, 4486276088811881},
+ {3865635552262096, 2111934227084997, 1803460783795098, 2595364764305293, 4294038033412459},
+ {1939054538963024, 1515892461529143, 2145315228101212, 206131396483318, 1207808442703235},
+ },
+ {
+ {4285235833599064, 5004869505494285, 5398338412388895, 5145057161859867, 6219558308357834},
+ {2122251221692966, 1686529461497383, 3592144721245791, 946103181235971, 2261774551055452},
+ {1519512635495115, 1879830706415200, 631994832099345, 90552542491442, 1074938948794598},
+ },
+ {
+ {4349405123860786, 3135193611243628, 4214940643324649, 5373877724549797, 3499285433136967},
+ {699708361184464, 2781323063917462, 1664177773796467, 2129061781951253, 2929310224293355},
+ {881819301152893, 1404208553713523, 1706641996539966, 685345252606027, 879987031868371},
+ },
+ {
+ {2629920833708073, 3077736686198199, 6153945246604194, 5109883364128321, 4007866927409167},
+ {2201062670972485, 2517508956278887, 2681660437016124, 2026769404043331, 1562746334284849},
+ {2029537774099989, 798336123274982, 962765795717174, 1441375461370721, 595792417755859},
+ },
+ {
+ {6147148440188849, 3255264873123981, 3737719663259093, 4820083084252873, 5252844759112604},
+ {2825984342500049, 2739886905391569, 1677188826435105, 1932192000687991, 3155126576093338},
+ {75347910850483, 59335245365512, 2051925237105745, 2044824231668461, 970303688628601},
+ },
+ {
+ {5763564504160432, 5421442243725773, 3588496091914407, 5369436266097375, 3995085142922692},
+ {2488955180168268, 1799719498283103, 3012193868704087, 3191119683274303, 1313407450591024},
+ {1669605168509235, 1046380333598262, 8317204728147, 1002144485955824, 1980712166998785},
+ },
+ {
+ {5208877095968696, 4101472145123500, 4547654469901586, 4596473001183302, 5108183921345691},
+ {1614319198851918, 1592777501272444, 2078178842786638, 1134074463419502, 3406886179792273},
+ {46520703266015, 1463053727782106, 1641431035629451, 1167993397224604, 1860200763335910},
+ },
+ },
+ {
+ {
+ {3011332796830409, 3293305844851756, 4350706657635174, 6528175041183782, 5633500660447495},
+ {1684548552982151, 2512680297050328, 2151565475089600, 2240257948464080, 2357334086387757},
+ {2245889758290233, 1304556815701186, 1427348922813143, 221464961710041, 2149077757654506},
+ },
+ {
+ {5021889171679330, 4462128123863397, 5496067810219064, 3884382915013647, 4592260500935750},
+ {1200977971745538, 679604753110803, 2370440117588934, 2264961098110051, 1017048311556208},
+ {1190992926530423, 1046016291129455, 1934369009614752, 958221374199446, 762751542850234},
+ },
+ {
+ {3460977055305417, 5402529018730102, 3060601098222640, 3497142554641379, 4775614304897016},
+ {1196600994744545, 1547369290503378, 2035231477477616, 1257032246257935, 2729013549752394},
+ {1316355169784636, 2159471323343549, 195437001734225, 1784725127680235, 23628188515854},
+ },
+ {
+ {4414887133757738, 4702915728776787, 4098231006823107, 4707645820548353, 4031420634244190},
+ {4034197670769956, 2299895540249251, 3720313013014369, 1169924369129605, 1452708652401532},
+ {246845927125542, 475207520380026, 1495857355234583, 1332907410765356, 1137190823002655},
+ },
+ {
+ {4619638086363716, 5112231939480403, 3430351651754637, 4072797244384643, 5452815353333736},
+ {402770419372162, 3130948749709529, 2422951975073025, 1521258543891683, 3268450338566556},
+ {122249525311324, 1126352422834922, 929325077009082, 782368628240853, 94217591211022},
+ },
+ {
+ {4962635153104108, 5274135403834507, 4755774461820061, 4383546262262835, 5457666487690905},
+ {2990995606289826, 3021922427972001, 302802129599791, 1502244105829111, 1773114045409669},
+ {156241863414061, 496518516536107, 402847929676013, 1139792271454333, 1977247161507402},
+ },
+ {
+ {5032814130431534, 4760678921877281, 4442869438253961, 5565429687944605, 4317400766530169},
+ {2463323770855702, 3896470221755473, 756431515781897, 3201672938286523, 2288460277235041},
+ {1855056967762827, 1495181328549832, 966278130514841, 758391654071223, 467588501531856},
+ },
+ {
+ {4817034814919500, 4208076967893683, 5868839484739037, 5852497340094076, 4630054499608831},
+ {2436900424213206, 1954148435588967, 1712385658617173, 2723793304425402, 681838917243489},
+ {1439947543028469, 885225692302481, 1285222886469976, 1588398795428018, 1298691185892088},
+ },
+ {
+ {3166915207030205, 4221727132556131, 5745276646060520, 5830694990900872, 4237998343894079},
+ {1368851636374513, 585540725726993, 2239345036245042, 3124363364569248, 2914970196697053},
+ {1206666555409985, 1789371104267935, 1925466428785716, 378678703847709, 378978574609534},
+ },
+ {
+ {3049990186077834, 4282707068721497, 4031467457902549, 5045270642251952, 5619239366726696},
+ {2247218341382540, 3733105160936895, 1542123681165149, 3690639696246556, 2686757663719606},
+ {1131525507915411, 151967851358587, 1334045685598637, 1807594577522576, 1666949318203671},
+ },
+ {
+ {5317642436905001, 4262905497079623, 3806587609027544, 3162214737577195, 4598325819108034},
+ {2322709256244499, 3364701239080335, 1085438519194966, 2211341194954781, 2734280485747362},
+ {547075051672667, 1927631982974242, 603999740914722, 1974345687792190, 310412755046628},
+ },
+ {
+ {3092260334664458, 6358353190373839, 4150234089958180, 4141601803005412, 4164851538431420},
+ {2480565549840732, 2510439995547619, 2534702111260990, 2561344597955166, 619102460354386},
+ {1996829248620682, 1059563669319507, 2240440638640706, 1599145288747177, 407659118560947},
+ },
+ {
+ {3115383537041122, 4344887992692310, 5501863024972572, 3993241570720752, 3416751871823654},
+ {1717619697579090, 3621794853637170, 2666986311609642, 3029150476191498, 2414353362640396},
+ {2142003785026841, 2167906365984504, 1742773278204754, 812925480008831, 429368090247755},
+ },
+ {
+ {4184856094603567, 5404235283771230, 3764176438258862, 4280121628742729, 3445790640140600},
+ {2656068733977443, 2976637537776442, 1238993222325972, 1554795161393303, 2131523863405492},
+ {1574345185045103, 2079161140310195, 2092484433153763, 1408980124437971, 44981420431371},
+ },
+ {
+ {6193742471986890, 3621814037880206, 5498721010846514, 4536848636334539, 4762288817182267},
+ {2703599140394458, 1961129680427764, 3192043467883058, 4259887504588631, 2455375021790255},
+ {1758602597767485, 709830862658938, 931608374711636, 2198476269423406, 69272189710304},
+ },
+ },
+ {
+ {
+ {3960691793618422, 4697205665896081, 4233023106925560, 3551947497905370, 3667490775726784},
+ {2716251404526112, 1631117916585969, 4014857913931082, 2213037729836094, 1396521499150134},
+ {296206175452724, 658879322369119, 97943562265366, 1761747874053347, 665498744562262},
+ },
+ {
+ {4542146017866057, 2313615921887147, 4181202139006694, 4414799599657545, 5341405847272363},
+ {1200760264207189, 2304738880112015, 1927960174691144, 1569518880089323, 1152309979337507},
+ {2038947849479643, 237162323211423, 2065816839891168, 419806183479203, 384865548997533},
+ },
+ {
+ {4632532202820720, 6679838284939842, 5003934316625137, 4209971835933588, 5519581415427037},
+ {1152764853239608, 2282089860477202, 1601380253073465, 898105377854964, 1583948862629235},
+ {1558193059260245, 1778073808602536, 402624851529717, 66752783641769, 824353727713740},
+ },
+ {
+ {4121947878564012, 3974762513146561, 4400688676047089, 3750758292493538, 5582121141429898},
+ {1987770197713484, 751549594590657, 4130774294058181, 2772087960475462, 2398377455469772},
+ {1021194340773145, 2214506742467645, 1946787888944335, 2047968106648641, 1821857137920583},
+ },
+ {
+ {4817011285691457, 3821500381976103, 5867746283021767, 5892999478528259, 3614975724251316},
+ {520345345283715, 993525428347841, 3082505540027545, 1401316007351695, 2524441889115400},
+ {540709883326476, 664748033877723, 77460650157458, 1882229467398241, 1217186023704288},
+ },
+ {
+ {3888704843022071, 3022592939512474, 5839771089230787, 4705593175556810, 4617871784452989},
+ {1148904473568401, 2292434344833748, 2860017655924869, 896886146116790, 1793557015614071},
+ {738867948290551, 1113067062951318, 2239418068162676, 2235388618772922, 321946428440080},
+ },
+ {
+ {5186369799189058, 3697173555759488, 4262727107695046, 3185380591286776, 4149807772745719},
+ {2507278187062390, 1965300287234722, 1455241861966706, 2358026574953040, 2356583034323921},
+ {1141974899967420, 1197500508248512, 1725264994009043, 1639228663875285, 1766256613674282},
+ },
+ {
+ {4859130511022316, 3438619274603782, 4274393918753007, 4542539306472407, 5021829178357491},
+ {1473307785816396, 2183888493524504, 3592230148429221, 2872086545946123, 718894511556159},
+ {200438687964996, 1579389594103736, 1144999901302662, 1292188560016150, 1342060233269448},
+ },
+ {
+ {5322785092917218, 3564464821553428, 2465159528975281, 5838118438127962, 4862308511365583},
+ {2206232904105334, 2908798660147806, 2169658158959269, 2724132358944628, 392390928972895},
+ {883459081700629, 1602090588151437, 768552508263143, 1181944834979084, 1796139787109480},
+ },
+ {
+ {5591293901585158, 5161437494483979, 4307878889760969, 4546298250229339, 4189604893397730},
+ {2182554744233356, 926666458178889, 2790825304990041, 2529147957716171, 951582391464256},
+ {187571578269437, 1207365261045700, 1671287753495621, 128062601272884, 1097620007687094},
+ },
+ {
+ {5979255840859055, 5170212343908976, 6251571908864416, 4044340797680332, 5873982661311143},
+ {1856097540852989, 989253754708050, 2232404724159712, 538127825012338, 2301974812680125},
+ {875553341339604, 2202671771469035, 1916683928798488, 1628926854796717, 2104927509529811},
+ },
+ {
+ {4738081053584946, 2875665464097852, 4082354471082712, 3079977082389326, 4643006842643895},
+ {4085499965974240, 2403823491084742, 3352533311494316, 2981802103584372, 2409154352569497},
+ {822917758900752, 1019777701975664, 1564136027018780, 1218107309963297, 1014127758290355},
+ },
+ {
+ {4211670720265322, 5260586114139374, 4117778612287885, 5761523698172883, 4942445429900242},
+ {2233928901439648, 3249090656816698, 2685023842449397, 2515328324903077, 2780554742949852},
+ {1119507853423473, 902873322434013, 1683813506511239, 99271672214794, 1043609318229518},
+ },
+ {
+ {4881172173279202, 3599812968457896, 5389450859587312, 4590538673755018, 5926347639505399},
+ {2643454724039014, 1385194776028482, 3573341970152704, 2554149121763820, 2626184303949707},
+ {1041863798926969, 1989079677249410, 910600041636905, 172639986070412, 958797345271109},
+ },
+ {
+ {4102514793801097, 3799057862785664, 3089506143944932, 2968464716766741, 4933382932746089},
+ {2671084000631505, 3069928136724336, 1615118202102194, 2860128525830493, 1072943882334681},
+ {2239551548278550, 1569208624262185, 270318489599140, 666224807173956, 272660472277513},
+ },
+ },
+ {
+ {
+ {3788400011322929, 5238791757709216, 4201438471307196, 5718998504437804, 4699660978114753},
+ {831848399557275, 2203944328508070, 1205773492199750, 2947899883606056, 1258775953756159},
+ {801855642469056, 1726062700700587, 1064722548099106, 1128997468587175, 1368420390253860},
+ },
+ {
+ {5220756346668707, 4207778951928942, 4451591079714714, 5561602467108901, 3701332347939515},
+ {1095027470911861, 1309452919940954, 2417363745862806, 3417231569067727, 1895316643922203},
+ {2142749866659158, 1962490102531981, 1691447155265793, 1827079035266074, 3803331638058},
+ },
+ {
+ {4981668826515757, 5644770367578110, 5443857182354756, 3149391452129516, 4066238206100559},
+ {3356282538281353, 2251921811216688, 2887149285344786, 1384857237573084, 4057072468959031},
+ {399619403797256, 1517816986720610, 1503473770785461, 1650204761619743, 2016574488970872},
+ },
+ {
+ {4082671840470154, 3874834197714005, 4437883298126266, 4222220664757293, 2316031680718393},
+ {1452497321657782, 1539338328736177, 4156757905713634, 1587402592924883, 2189645592400953},
+ {481460971838645, 495603062939192, 2081146895236470, 971761350637757, 742727604094484},
+ },
+ {
+ {5515673501962670, 4546389793895825, 5000269413610660, 4603828815474748, 3900836987569214},
+ {2460924811417180, 3521984551624439, 1511404974611240, 375249799211988, 3782407540620780},
+ {2048665788177445, 1408893800498572, 1918636993246022, 317961445367427, 656800592778138},
+ },
+ {
+ {2426976075633155, 3651600221015543, 3234264849290625, 2473309309095632, 4407296503206636},
+ {2422350949934017, 943103623278343, 1291301021890213, 2346315203451818, 4112725099426082},
+ {269878912827170, 1290670313639785, 2170448731381563, 1730590899024060, 665688666929019},
+ },
+ {
+ {5000413361992888, 3347912965056552, 5787242209541388, 3819792442922756, 4847625000360540},
+ {1580177441875156, 2506058297611016, 2934789696579346, 1061310370544480, 596660656376680},
+ {1957905575869340, 963138800079095, 1346185076450932, 33814819376238, 1624717058267694},
+ },
+ {
+ {2861980301667765, 3354887551296141, 3948074513800240, 4019265998902801, 4754514631586968},
+ {1661216359883315, 1198665005326425, 3475476495296842, 881743418686047, 635325796191538},
+ {1196599610725063, 2100294611545468, 412113633351820, 925880965367657, 519930913383517},
+ },
+ {
+ {5571468672275863, 5188072583684019, 4251873319339365, 2576514881889354, 4045293404267572},
+ {2133507738629437, 1327217318093765, 1889369311142453, 2479101608310052, 4045149986308216},
+ {703846410484025, 1348842341032186, 1685275777321460, 1615795108904065, 1475415532006380},
+ },
+ {
+ {5398949984609248, 3762655856514160, 2412712349948059, 5169973908847336, 4334869322214508},
+ {2999632416625302, 3110726069588902, 2228895586394623, 2800522251491198, 2224895404394358},
+ {1399061587160944, 1205421803029276, 519683572464804, 340023786200115, 2172700699519595},
+ },
+ {
+ {3574689489677767, 5335925023065998, 5369256661040087, 3129592424352108, 5388737531811449},
+ {2700892402458353, 2743476698281872, 1953844576554527, 1836651043988628, 2962536972306493},
+ {1357694877428531, 1765161852606993, 1167042823088862, 1400958578522448, 1847208195529391},
+ },
+ {
+ {3867728253589687, 3773111053869328, 4368860594965835, 6133882052967679, 2533060702765705},
+ {2290736769578191, 3757556884488538, 782075793204873, 1953945334364505, 2306213589322841},
+ {1820300206186415, 335405661683482, 1092574996911739, 2062461927997493, 39506950020151},
+ },
+ {
+ {5534612992751919, 3746157517504511, 4108089392798474, 5131771932089590, 5617809945843001},
+ {1342645331878441, 2000053418116353, 2168383944146424, 681027567941522, 1213562615764099},
+ {379321638440622, 996302411355145, 1880571763884906, 1004856333759537, 501836588196832},
+ },
+ {
+ {4231662813561705, 4640318983129989, 3064518357303150, 5343343094006261, 6450142130522077},
+ {1145892199839501, 1078673486712789, 3022417549910920, 1612895247211701, 2324179764588241},
+ {1972676776834949, 44492199500322, 1456097929669866, 211262343295697, 1045510624803264},
+ },
+ {
+ {5968931973016112, 6019428128447854, 5757013441564652, 4431402751536781, 3192943415309330},
+ {1480229165025206, 2054505377286776, 3099784048655970, 3055900157449953, 1375885673210420},
+ {1812738520892942, 2084676765238369, 510773948276259, 934572202757904, 537600238103234},
+ },
+ },
+ {
+ {
+ {3613080834135665, 5774088788979550, 4480966629462376, 4981692702949983, 5531898286124606},
+ {1941100238292769, 1530763972357988, 2941717574786124, 517834246099701, 3268301290369396},
+ {402477551873128, 1206353712079331, 1931900782149571, 353151698548753, 227661813611943},
+ },
+ {
+ {5770945118915754, 5544555209532203, 5448202195803091, 2841016429831070, 4428081881985983},
+ {3042160696267866, 1193039775906917, 2708874250955853, 1880772252763310, 1647664574467171},
+ {1801318854301087, 529217444026518, 41439150499132, 1819497139150034, 1914318279506430},
+ },
+ {
+ {4617843866085510, 3963473780045850, 4530695843220841, 5152831422757274, 6255165884461126},
+ {3653392334037390, 2119290268348412, 1662789932544495, 3712853444146946, 1761023449047586},
+ {1892648843913435, 1079776332626104, 1111039290977790, 1827479485396386, 859677304170245},
+ },
+ {
+ {6135115193251795, 4578420287793605, 3485955900327480, 5405600312155654, 4983545824887909},
+ {1955745180210457, 1703319703537271, 2019166049085294, 3363246542620192, 3873119138750761},
+ {1700391063795585, 361747633083750, 1216968456947850, 1993842710713264, 601267006969711},
+ },
+ {
+ {4925286822096059, 5955810075280268, 4224518592023607, 4497079033823924, 4700697585549198},
+ {1335348453199749, 2692696552964594, 3243268312448681, 1958567111536422, 1194502970771976},
+ {1656217138482787, 491628805607466, 1679451179466805, 970181505842258, 1534105889461948},
+ },
+ {
+ {4204969625278834, 2839735694548476, 5311815348914771, 3424730456556302, 5437312551033891},
+ {1051919605857270, 2689758516764280, 3195630903391853, 2321619474659180, 1445811115388039},
+ {1160289603260459, 1956223108351205, 1733312353955470, 208731931777063, 2163609865075088},
+ },
+ {
+ {6171922307530267, 3416689909413961, 4398780048782414, 3348704297294309, 4794281577167533},
+ {2605760676899691, 2518935989171471, 1655039766011588, 2352706753121153, 1606429966007503},
+ {1142834714776341, 85770505106288, 713866520631433, 440023537352050, 178697006218663},
+ },
+ {
+ {5369775152479351, 2976619105904851, 4320166487861154, 4349283416973378, 5052617030572584},
+ {1815823837273367, 2562753791013569, 1539789395052836, 3647749880076906, 1631063017998020},
+ {534961844628464, 1393583055120721, 1748351260324708, 1375538226727024, 2193309623120304},
+ },
+ {
+ {4362511965756519, 3334861441534551, 3560279110881819, 4504033277345817, 3695270180099552},
+ {872424258749169, 3269419467389617, 2236476348626173, 2024356220545311, 2898783963621386},
+ {1239822839121281, 1734625037061034, 1644113104753887, 838912630061655, 2165081997489666},
+ },
+ {
+ {4719668160615989, 4954232553381592, 3407504093515639, 6056696583065019, 4080126483053229},
+ {2648578609770085, 3690844259333424, 2082598280716609, 2564691042641275, 1346520144951773},
+ {1979149515238517, 717801405945362, 2104011649567412, 1561125545440573, 2157118688047562},
+ },
+ {
+ {4177174713439601, 5431484182531219, 4912403072956818, 3423215719262779, 6067629588380508},
+ {1808742790957793, 2747803311617739, 3845306078978452, 1924084822718509, 2264852519642740},
+ {1767189866398838, 835676264200014, 201596448765126, 1979907908451931, 1442810524651041},
+ },
+ {
+ {4409296057792696, 4346067875211154, 3459237364299404, 4853798679576266, 4468808308660588},
+ {128841748532646, 4150186054273698, 3256924437045680, 4019614742906956, 337338633748078},
+ {1077226425497346, 607378044682866, 1485491791574172, 1074180848747199, 1023053128705595},
+ },
+ {
+ {5804603278915694, 2796027819585631, 5011026665884139, 5833743165576011, 5103566912764066},
+ {2493359374165148, 2464080592904187, 1933101226851633, 1880342534882667, 2417917477223840},
+ {1284426144747169, 2005093245564178, 229493920382094, 1642769566056222, 1596652614163344},
+ },
+ {
+ {4478501502615841, 5105996638711000, 4307245809257853, 2912192821294412, 4442483575340114},
+ {3490678780709549, 2722972627744756, 4141726367382933, 2626667232874306, 3706338015195278},
+ {978951056774557, 1610590016630807, 2160020521521822, 2222969528403014, 1290838415735858},
+ },
+ {
+ {4233395101645091, 4760048839668621, 3419853204404814, 3555462417010423, 4295491197124032},
+ {3136023326660957, 3195581484142287, 2364500047372050, 978391045278571, 2088093684065312},
+ {319754006496675, 2078141843592369, 1381704035073408, 2135424637477137, 1217419566529670},
+ },
+ },
+ {
+ {
+ {5290773769928918, 4793813444262905, 4720763845546248, 4081316225438835, 4093406366409350},
+ {2219813055094868, 3751054103166673, 764148091645988, 3042364539660805, 2174498914560536},
+ {1346839273131020, 1947175237418499, 2130499171815608, 841760904333801, 793011313347544},
+ },
+ {
+ {3890099439122631, 5436725454634839, 3526358179473960, 4130205528836253, 4143183670329231},
+ {2705685430041151, 1931337763813343, 1867986078235466, 963301853857219, 3203544659615889},
+ {548016394257586, 1770170736821935, 883041007523403, 1244492123782548, 1874837894534970},
+ },
+ {
+ {6107029440448048, 3899130796270571, 5350832732145407, 5288086135111572, 5016688224136320},
+ {2322745137203416, 3712079434453421, 1656136902347805, 1063047643279494, 2347290530652372},
+ {1585044732618145, 79674660750176, 2047172033863331, 558016866726219, 1811700039750197},
+ },
+ {
+ {2903508896190354, 3572836747669154, 5671992452104047, 3145254132994495, 4870698970274559},
+ {1980868732324310, 2459850087283418, 1500353534094477, 1977074025846907, 686785408890947},
+ {1977199595236300, 927859862391871, 2045825765550850, 1189431662969386, 451125616133550},
+ },
+ {
+ {4264958907260919, 4637613300323186, 4723189721727247, 6439587034668993, 4270210266819895},
+ {1981177153373343, 1776706813610008, 2956634306768875, 2113399644330229, 364175990188877},
+ {1473984112024647, 2212143402178000, 1913009700964560, 489799262080055, 1390546130501803},
+ },
+ {
+ {4617432771154388, 2768922884406316, 3194759053322417, 3846588214005790, 4684848439540931},
+ {3696338004009516, 2296500736839486, 1483385825107721, 732704435299560, 4093200809844903},
+ {781495195344331, 819872919567170, 2058369589741763, 131552040816437, 1143952030551876},
+ },
+ {
+ {6045398880892501, 3274164683120730, 3537206235588588, 4953070760072151, 4494335279262109},
+ {1632591054957791, 1584029964350608, 1679919371947982, 3412378076716233, 2572356071530817},
+ {118276417181988, 2048136038162801, 1736078553924029, 677257986431580, 711847529279284},
+ },
+ {
+ {3634115225339518, 3407128374975375, 2997970212274081, 3493862836273928, 3535607408159120},
+ {3574732327388664, 2600283522407089, 2877235052318169, 1647316986471086, 1495874784707614},
+ {889518489432828, 1216748566987677, 2027061052060458, 268044074097160, 1539610510772867},
+ },
+ {
+ {4611501240201625, 4770963666624495, 4338415201879424, 4860883825935208, 4028006785359735},
+ {259543849715615, 3116307281996357, 1555340861337048, 2140193697629416, 1035789313751911},
+ {1026218773492650, 930245039288082, 1822875264087643, 479782375672284, 1931812455503119},
+ },
+ {
+ {4148807861057856, 5812728864755237, 4601316267327746, 6043565150382029, 4199151665681887},
+ {3394871127325058, 3191785534223821, 2085795470524552, 2385926585602461, 399655200529949},
+ {1057229833653287, 1828041669558530, 1006577782987596, 2162474092618005, 1568476132284973},
+ },
+ {
+ {5547684346917888, 4989218016843942, 4586613652979209, 4863124308009928, 6207570019680129},
+ {2566237642336854, 3970491812994094, 2598212316441047, 2240782240471054, 2552742376593093},
+ {716486226259134, 773421749453144, 1784612269854183, 1741938572500414, 1834164482186148},
+ },
+ {
+ {3117421109623856, 3461685839753353, 4955306417606165, 4558294861196235, 5602064404959934},
+ {2273224772261066, 1223111129900149, 1584682650834635, 2022200125401455, 1373728084078920},
+ {913182622593832, 2001872744868184, 882970207556847, 299806317329996, 1726046908726060},
+ },
+ {
+ {6249588231739606, 3368998262120903, 5239047789721372, 3406210943086424, 4754518606052966},
+ {2248618336554706, 1339184282498129, 769038678141320, 3217160515726744, 1715873134108166},
+ {1976228100247818, 1272400462149307, 1572190226615598, 852044049472028, 1055275428347366},
+ },
+ {
+ {5284373775928701, 3618431820022764, 4020557586503952, 4433032839002146, 4171326821228907},
+ {2417108732168755, 2170003784635000, 3518440054867754, 3152772966589030, 704341378948759},
+ {1290493724571150, 2122276831263561, 1747969631590180, 1399718798480988, 139803941068636},
+ },
+ {
+ {4427994415528072, 5149611644022833, 5193849655888518, 3398788549762908, 6113634201730634},
+ {216319500947386, 1455486684654953, 828483179169328, 2183296040357724, 2625210482982860},
+ {478303205586551, 304131100485205, 248369703081454, 371320991720787, 1635813582756365},
+ },
+ },
+ {
+ {
+ {5252346966668309, 5639208782676701, 4075417215389880, 4364690112290244, 3384680235809138},
+ {2429491642409009, 1283094434250487, 3316839113847160, 4229629869361324, 2675780619596520},
+ {2176454779743876, 931093459142961, 2244697379845986, 723779257225747, 962795008037376},
+ },
+ {
+ {4164637625281563, 5566305816206016, 4655415916130208, 4180775155367792, 5707768410211632},
+ {1861517597691605, 1772481620932890, 2629476438960640, 2705827759458320, 2107910124630170},
+ {683279446283480, 2167544438614321, 1975855992985379, 780955320484514, 780910621778643},
+ },
+ {
+ {3955544259328322, 4458238333874171, 5864190420414532, 4345033257929994, 2857162289792042},
+ {2686358254975148, 4179751356732233, 2499687248272490, 1241163995738960, 2778131269016956},
+ {1074884828909420, 432905047961772, 1185537826254838, 52144045776742, 1826277929133963},
+ },
+ {
+ {5684453359674447, 4877177488298427, 2422407833284604, 4605478777171110, 4729984701613103},
+ {2156715047802967, 1276772803921323, 2380233522537438, 1960794365816568, 2680384519257273},
+ {1862177374063425, 1873700738552432, 308885709393483, 2100622082080360, 1104535253282502},
+ },
+ {
+ {3931149063775879, 4254429699498962, 6662929352488607, 4079587572542558, 4855364761755442},
+ {3711640686247983, 421582154826228, 2220646689506683, 1208894292386914, 2152820272048462},
+ {1565335522994081, 54406341126738, 599331788389250, 1486039135212823, 940991227185565},
+ },
+ {
+ {4398457498029638, 4929754658751446, 3952574300737926, 4493043596943885, 5305461811863411},
+ {3849064215739384, 4001520908708098, 3463231867051918, 3642198741522237, 1030072339730421},
+ {225800753248600, 1001289196776939, 1570695157447337, 474142387326152, 1860241406570283},
+ },
+ {
+ {4817367953033495, 5599987240264127, 4736311445242884, 5430531336232182, 4460173530026570},
+ {1052973111938531, 2823516883980375, 662638871434014, 2738994056625648, 563864123356550},
+ {823857549390635, 2207592640971793, 1855512257490888, 1911413747439725, 1853809846918105},
+ },
+ {
+ {6194718989753531, 3626032976625365, 3751630707315810, 4477700840286220, 5452904257109698},
+ {2036109024667887, 3040585821349743, 2780985384011476, 1970818175728284, 2968438634461420},
+ {695616701038646, 20368455765111, 619664083096696, 723635083382804, 1023760209767255},
+ },
+ {
+ {5008707213573776, 2859949901187285, 4290065003741713, 5151870738966180, 3127611889915462},
+ {574462324973718, 2125329428751385, 570545018291281, 1476031513731508, 2680835412613570},
+ {1517596182333361, 1429983941782802, 1900615890395770, 1911469027059364, 1851356681596334},
+ },
+ {
+ {4891662727757105, 6078189791872620, 4341252688115798, 4009612276132060, 4158882628774497},
+ {2178830616846417, 2794898270987790, 2339865206643716, 2923242275980220, 1745466521002355},
+ {841969861771844, 1234567333486718, 2104638753106763, 1445233761721300, 2209267998342752},
+ },
+ {
+ {6440345201923204, 5723637287574387, 5903930483115066, 5778502423080164, 5079904071191760},
+ {2035275243828198, 2745418930619871, 2632830605513978, 2519743098631716, 707209224772602},
+ {2049800384050253, 382336843047910, 1465264697408643, 242728978654073, 1821420259893325},
+ },
+ {
+ {3385848358825911, 2850931104925851, 3458310588278305, 4579597908985563, 4607881337942919},
+ {1816700573507985, 2213627388818419, 2637198541463171, 3087473887817081, 2837589033715179},
+ {1073720617318924, 1636814037227948, 1227321319951543, 598345156599653, 544027576937438},
+ },
+ {
+ {3741365114761762, 3465142572701024, 4346453033629668, 3800732328304411, 5207004929940855},
+ {3530134215235346, 1497788707695478, 3538247705814828, 1425334926184197, 3292646832985731},
+ {368165631658486, 1427424960871770, 667823977725231, 123986789130850, 789476314816796},
+ },
+ {
+ {5183377371949700, 4172584964939172, 4687335701106073, 2534986101578472, 4297053492878574},
+ {2375597255557748, 846038920993436, 1398943082722053, 2179038637021886, 325133433602556},
+ {1814357252172511, 1812991482130874, 1545461112716185, 2228739665628687, 1030416912136148},
+ },
+ {
+ {4102150726478441, 5089888860858732, 3167069131929673, 3336166645247640, 4708635432875520},
+ {1325239906989203, 2989936170895398, 2414201768248283, 1851733918704382, 3428546124237928},
+ {296568059020374, 1937661788490502, 1994712548479216, 1341415580517821, 919259617560208},
+ },
+ },
+ {
+ {
+ {6274182990169406, 4386048988056353, 4097025350643424, 5127499815238002, 5572164902186574},
+ {1895408474337392, 1335954976788533, 3236941534902540, 2378721630147940, 1461766309882914},
+ {1291953286798969, 2102679466898679, 1596002078575263, 1387588817990761, 2143444637427225},
+ },
+ {
+ {5996694561997207, 5683227612437284, 4899213524992592, 4856689735436656, 6404791836913969},
+ {2772496102790967, 2917238652453944, 1731727230740742, 2247887220248582, 2143609474706149},
+ {923819152192005, 1415712944791087, 1125410698033067, 788009900900011, 869993295869018},
+ },
+ {
+ {4786795669239288, 3398808358640920, 4513626939909643, 5985598090247291, 2945790096837940},
+ {2456756643078196, 3060894189290238, 3759434421535873, 2442805763764489, 2819028797217160},
+ {1757819380032415, 1458259160758992, 404747119062789, 1242483165113555, 1521264843142355},
+ },
+ {
+ {4457446227801342, 6427880138295914, 6656730008666805, 3937171933580687, 5754864538579708},
+ {1177246463904108, 2488433613267172, 2328478208484747, 3802230570654315, 2344609059443716},
+ {1519155588261854, 483899768651806, 1235345257217886, 467640517750393, 1224438957323827},
+ },
+ {
+ {5102603430061893, 3128470923287158, 5801341356388264, 4525678559978591, 4718363529583899},
+ {1246208485680505, 2848653521425806, 2416405253631000, 3077610602170527, 831805919056409},
+ {2045656886162419, 2245569838876242, 1361334406977685, 1370170063372453, 1784586163491838},
+ },
+ {
+ {4556063502635342, 5531207665521536, 4057497943029825, 4507014901377590, 3148382369498868},
+ {737891874041388, 2451689755512888, 2972729929575783, 1153163677723624, 2631153364835664},
+ {1021578499394252, 2003506226907156, 1906928204664703, 617432881327189, 487770381544088},
+ },
+ {
+ {2772215428108171, 4464024296635705, 4854458470465137, 4051326172605262, 4041843916653002},
+ {1808240492311657, 683215352347115, 2786075502512133, 2784661866757750, 3917451132840122},
+ {956648481954026, 2096247164218896, 1027480742584033, 928233599700570, 2122240338574709},
+ },
+ {
+ {4629946233006760, 5291553581528148, 3270843847622640, 6572477208034336, 6154625523788459},
+ {629205712253428, 2948018954745502, 2240941577462354, 2419373201820060, 2682153541398885},
+ {948811544154236, 95827271348811, 971972540788513, 1752656910961976, 1577613288465037},
+ },
+ {
+ {5687495579915904, 5920739705585144, 3623686905482864, 4279799360588693, 4937051703985742},
+ {2733819029729102, 2941383700719094, 2344126789319304, 272099344396033, 3469931440006564},
+ {1155109808876838, 498663775049656, 2009409241380161, 1654861553852237, 2195711930770443},
+ },
+ {
+ {4562514450276878, 3610360397280214, 3754786033717112, 6274151337271952, 4102082344471456},
+ {3779237395015718, 2531855739502292, 1076300728317328, 2341702386635930, 2037036009072308},
+ {357187236460800, 1343207422743391, 1557831743447331, 138875622916216, 2073308474766668},
+ },
+ {
+ {4318248447888802, 5457191060945059, 3575720381879889, 5537122891348075, 4658291618481620},
+ {1058927027601226, 2097000197595935, 3018484019405255, 1294660112618737, 2932877913314978},
+ {216145844764492, 1876995804123388, 1188737931982599, 1588244200049402, 1850009625550870},
+ },
+ {
+ {3352537291082093, 5839102984451201, 2319458858510810, 5312519694669356, 2539572161961088},
+ {1971880260906249, 2590822963635857, 2283171542295386, 888730652847270, 2069077006720618},
+ {986114249350619, 899447833294837, 753796294360457, 1686315816498457, 1484432111173806},
+ },
+ {
+ {5781412563046772, 2829048727661187, 4098529237644982, 5146692071916491, 4319033371720950},
+ {2231959129524362, 2353147866489543, 1361542642038984, 3436571318049649, 613122764422636},
+ {1553151906564201, 42706246613546, 1656634422023210, 337580524133816, 1382068281260380},
+ },
+ {
+ {4318188098974879, 4190975253205867, 5053353859489555, 3624409471895100, 5734877817656224},
+ {339244995001665, 1760160432424305, 2510143032086917, 900873257630652, 1381243383153778},
+ {1027887039599863, 645983151773049, 940633405940384, 791297293294468, 113951612418342},
+ },
+ {
+ {4421127861301280, 3227473132618256, 3897823766346675, 4531675054348192, 2597262173415879},
+ {497984229256388, 1528193624284798, 3083402776323261, 2834076054300848, 2004534517066737},
+ {707308783184531, 1723910086807466, 791458836921758, 441590831592448, 1945299136569002},
+ },
+ },
+ {
+ {
+ {5139590791061503, 5074296034161507, 3861111523264964, 4286794753368429, 4613589462411916},
+ {1370912655100557, 2279879075953359, 1535348789227130, 2242808749632369, 3061442465980918},
+ {2128769772677977, 2142654242576520, 2016094652496998, 2132031230853467, 725434888027655},
+ },
+ {
+ {4677803618766960, 5273930469290190, 4617970826042730, 4133081282480847, 4583310983505940},
+ {2135073895739904, 3472442449797848, 1493509767807810, 3843639135014989, 1420071562059334},
+ {1420603492551010, 679640550295814, 1617533903828801, 780154362635607, 1319780020899258},
+ },
+ {
+ {3937068127551315, 5594824685351819, 4538337787238312, 3523378410763828, 5437114214061846},
+ {3695575212053185, 2594449599707103, 2742930959436192, 1161286236132678, 2345020968733648},
+ {194815921686333, 1256736762545940, 1408742447743650, 304562218341097, 2021464306176092},
+ },
+ {
+ {3212222966285493, 3266851872779616, 4336733687401440, 4794872810759007, 4424169619295461},
+ {2759763070229743, 2724175318859802, 3031057691838938, 3431189823632909, 2961517144339711},
+ {440075250919582, 694825884103652, 2159700403414911, 116894270435230, 1425927073727904},
+ },
+ {
+ {4841955313295828, 3461757100553382, 4305435906781420, 3691116875116057, 5298851817605162},
+ {1064910415642974, 3095607189587094, 3908971853500052, 2189460887246833, 1354043476687700},
+ {1262675707031055, 1219816744922490, 519257628155087, 1497570437960201, 1372594887264798},
+ },
+ {
+ {5466094472208141, 5012579346250577, 4661027376097750, 4434802656317810, 3968075278352583},
+ {3315525263287981, 943900907578117, 1225723797770692, 4182671057889152, 2697481958411475},
+ {1933555860608921, 1275569655188916, 234812135397482, 96042287368239, 386392083574324},
+ },
+ {
+ {3319477981428303, 4681888525996228, 6591617607940267, 2604452186053658, 2972488992219816},
+ {2831773176554005, 3864996001314642, 2395563170308483, 2090271503443448, 1893990359510416},
+ {1681588555670186, 980191207008201, 2154581399538671, 540872424183046, 1943954489289499},
+ },
+ {
+ {5977124761029192, 4538331973533215, 5533519881915667, 3479901172100047, 4656405250637608},
+ {2363082790805374, 4242757803000485, 2669759818118169, 3333816374844969, 1325118659202748},
+ {183359648873960, 382111728086623, 1969766109298473, 2071169946252387, 242935538497060},
+ },
+ {
+ {5188738692165469, 2664732629276594, 4968279324223179, 4960443399326301, 4436427572176893},
+ {3490990196257229, 2560345203268680, 794851537166791, 1532423795715657, 621302931359813},
+ {440189527159075, 2095498912423497, 1575373142262611, 744594360742511, 1157079567398109},
+ },
+ {
+ {4869958177792820, 3889970905101269, 4570550615789326, 4496205440964732, 3848931098885666},
+ {3870071548603662, 3041096274835181, 2350925463456272, 1091637746528482, 1355815234248438},
+ {927792763323382, 1304575354366273, 612939300770904, 1630367810979451, 174107168815644},
+ },
+ {
+ {6136927367908702, 5203222247970547, 4888252310796559, 4897189790028520, 4586519387439588},
+ {2831448685067634, 1668205588574421, 3161976938852725, 1027424964992432, 2026369259616642},
+ {1735694076750726, 1266349638286480, 1493849675863588, 296961022463490, 1483126610434799},
+ },
+ {
+ {4654087895073878, 3931119431920957, 3810992402627745, 4571904269427127, 4481981159091504},
+ {2466558329032204, 2314404658847041, 2524639581935109, 805442192808499, 1270294344302086},
+ {750996510156456, 401855193068398, 58073276915611, 87767580153872, 241880537805683},
+ },
+ {
+ {6336062814229381, 5495468976405173, 3085611334327622, 3929566749867368, 4056705138744772},
+ {2170745323194467, 1059898966987983, 1821678094574528, 3224522071822304, 3177794562815748},
+ {697769608468752, 1369430004061620, 1388586673198089, 909114275708814, 1146450457999407},
+ },
+ {
+ {4238043779316857, 3868604149115822, 3602737573195351, 4491948926777684, 2593111277688382},
+ {1942420724187743, 1230266918978492, 2950156777850293, 1491177343837674, 2151732388834046},
+ {1552628609460396, 385059438618066, 1935679554618991, 1586643703562239, 274738755241324},
+ },
+ {
+ {3708634080771636, 3376471647619972, 4144079859874091, 5260099970974267, 5044960426451952},
+ {1260464362728368, 2320200151112594, 3280988120127265, 1454370155862373, 3222503455600234},
+ {1286187906300863, 286639393218233, 960541512944676, 756511343610150, 732619979206969},
+ },
+ },
+ {
+ {
+ {5720776037989329, 3408557855252881, 2836745411300455, 4905300285896935, 2440518813003965},
+ {2216608521812979, 1133671267609171, 1886801270451833, 693723450681229, 2177664326279079},
+ {2233307833752057, 720411965215730, 1519169695491573, 1249545629073374, 42274079495163},
+ },
+ {
+ {5289248568149457, 3817875509053716, 4457685664702894, 4876101051290378, 4294494794724040},
+ {3280020244834293, 1318628129209810, 3119398368735896, 391516159010622, 618793687544686},
+ {354305362086679, 1512134460741612, 359672307646707, 182487842123724, 70434142068276},
+ },
+ {
+ {3945557653570869, 3088092003227000, 5454351386185562, 3234451172420338, 4724702104276340},
+ {3276624651778803, 2433844765263326, 2790865929084436, 1963658167580138, 3140414260467690},
+ {46706548238824, 1986500518838735, 2027136585204085, 1143580830274421, 237034819567290},
+ },
+ {
+ {3929429576586958, 2793383744028645, 5887317021163886, 3203394573309402, 4670385004087593},
+ {3462257554153900, 2215903401275259, 1545855048122212, 1560256833448838, 235678314205821},
+ {1032532177573683, 1507169914894481, 893954872249259, 1464210961075811, 2248024514969267},
+ },
+ {
+ {2517873563818259, 5567259846017152, 4253295986752699, 5558170137710973, 4039120007239859},
+ {2215196432839229, 1453988298479780, 3162959582154309, 1417180860727485, 1916001465630095},
+ {1593076635649167, 613414152324278, 1398118686752976, 1550186634066418, 2024312475795755},
+ },
+ {
+ {4524027900175525, 4847878416694692, 3091409665235077, 4862578993236379, 5350599804185218},
+ {1611115816843085, 1564686497935112, 2631443498765253, 2543391790063645, 1070282314438176},
+ {1370619542022553, 13593976629245, 670888839522668, 29909561835083, 1113994299778657},
+ },
+ {
+ {2995680265327027, 5241715165954044, 3953258701883675, 3989602332635833, 3953848187775337},
+ {2462467670415027, 3084380814586442, 979195344857407, 761623507948939, 2354116769190033},
+ {1653806661942935, 798938977173667, 1204504651898865, 2012775328403335, 959133953735021},
+ },
+ {
+ {4988340255562522, 6250762111649497, 4210027774413747, 4281026073914171, 4124289570254779},
+ {3308091097868222, 2438171792492677, 666572176305849, 2221533064225315, 1302577527793701},
+ {2246982488380161, 704048527252770, 449031029656446, 2000971659049725, 1830758195793359},
+ },
+ {
+ {3190675561821798, 6722820056714491, 5018399111078811, 5991624407670525, 4249280343842061},
+ {3052270247598664, 2252472217742059, 2434081171992329, 2672797197928279, 2602890651310523},
+ {2144671346446832, 542864631780587, 1155108742000404, 1404732713614448, 240293866423412},
+ },
+ {
+ {5121381423145567, 4833873167604293, 4028173334112257, 5524034306881884, 6230562353876706},
+ {1307308592059221, 784383479594685, 1720750519626457, 1912081034355222, 2024784929774716},
+ {22174994285057, 375276401373336, 1210941030392323, 1903374444438123, 1011323371888298},
+ },
+ {
+ {4798470629258750, 3939993567755513, 3967862752630070, 3290332526819821, 3061464921693387},
+ {2998794565294986, 2057935584763381, 2899577223808862, 1519188817940759, 1842063844888831},
+ {892208073348264, 1880270486117637, 1866139692669281, 577642276098528, 159304923876906},
+ },
+ {
+ {4601033632870689, 5799253896657058, 5779104046600604, 4218473381777077, 5066296163965867},
+ {3118817410699903, 1416293682313136, 1358642285736990, 4016697695252823, 3785048363131621},
+ {841452637470330, 509851329084465, 315943768852800, 745051417948746, 1317978823624451},
+ },
+ {
+ {2960724265045759, 3581409910547792, 4757575913235420, 6009932939538924, 4725476498610383},
+ {2216474880678649, 1883045416719140, 3557095587267860, 2414252121862082, 3019618269128831},
+ {1790146986408439, 1266311794146205, 923857310756466, 2043374401317120, 726369229085659},
+ },
+ {
+ {4878312571596775, 4222794967531206, 3321677379160160, 3406594510676891, 4743132105473153},
+ {1047639500605479, 3268483579465284, 2206428670313250, 1688287562131353, 1668007864663417},
+ {1777656298881359, 367886496899263, 1134571758927624, 161297709883194, 864111924164392},
+ },
+ {
+ {4770637647109604, 5356580318440110, 6456410085143486, 5251963198009528, 4612863117603799},
+ {3459496839496426, 1172866796116672, 2087657719164010, 3611579473502448, 2226199443508323},
+ {179962092093812, 1434865358203901, 1509301171184812, 465007053005824, 1606826267425619},
+ },
+ },
+ {
+ {
+ {4321570421086801, 5728967329483361, 3790752945733902, 4440201295898093, 4632192800649486},
+ {477207916553285, 1488064260202941, 1661453866463954, 1141228074051855, 672072650786576},
+ {916404312971536, 1000014350915647, 1498754584389763, 67530592482209, 1667646385756724},
+ },
+ {
+ {3838511633005352, 3067059108181153, 5859654687359949, 4517853996250692, 5491933645129578},
+ {810369747020164, 2237618141036509, 2282241440976077, 396142955464532, 2314156456627292},
+ {498205650210982, 2029447832739442, 1287708517665602, 2063154761502015, 592549403529808},
+ },
+ {
+ {4850172605519114, 4864656344540316, 4532814144934823, 3437824613452670, 4812474608554159},
+ {1466752538541840, 2035538193320560, 138132610685025, 1256421706559322, 2431850955679681},
+ {1297525937307453, 1360474818962172, 1057976529132470, 481516036122456, 1284896343639676},
+ },
+ {
+ {5776741280656995, 5103737594811281, 3360081478971068, 6111393754727746, 4779680024426854},
+ {2645933668955707, 3274005597891379, 2656619141981518, 1746214054851430, 3053032647501696},
+ {1625278703177771, 652272403287866, 1130860155562117, 1467718191751280, 170296377586353},
+ },
+ {
+ {5094219073783849, 5735075135248235, 5606322495206271, 3754059419692243, 4180105537366398},
+ {1002349488419261, 3232903243006485, 1398184721429427, 3601262477434907, 4062926820203090},
+ {1577778325058339, 2215369962281551, 1331723269758849, 1939632256423674, 52886968354553},
+ },
+ {
+ {4933187999581607, 5092493367263378, 3356435735616918, 5217407324510779, 5497406740649621},
+ {2729077630033003, 1888615867921888, 2296393402013134, 839924021249031, 1005736290727363},
+ {1035587952296453, 772571610990610, 1703146381743864, 447715678256778, 1714287687955168},
+ },
+ {
+ {3002761637349276, 4331640081948673, 3834120280377754, 5089609293083651, 3261373019366335},
+ {2386307482062396, 240967146617557, 971317535064000, 2019271157069067, 1502539203059821},
+ {1328811798417377, 1232170334974369, 1723370191641238, 2166559558468187, 1898556240276951},
+ },
+ {
+ {3941047590826269, 4239692035015583, 4490403838767533, 6564872456977192, 4670461766802655},
+ {1386180360119611, 3273074614881159, 1729880193705623, 2228606406348098, 1592392117444361},
+ {419731549689034, 1989626747750813, 1591278351630992, 1092786235861584, 177178675215960},
+ },
+ {
+ {3436683241673758, 3662206674778039, 4373967447323555, 4097363846812803, 4031597646782708},
+ {2639672814451512, 3326947991249179, 1680625793199947, 2034248047548953, 721741001003862},
+ {1591050698007192, 1091674239474205, 394086386458446, 652864259466208, 252826649880832},
+ },
+ {
+ {6202959881484310, 3301137131128391, 3338332791366416, 4386834101046813, 4586134902683138},
+ {1761951583445986, 1682354370625515, 1311814077921538, 2232552485157187, 352715570060390},
+ {1983847550347734, 1877133028995354, 991701922936357, 942306684083689, 199141297262892},
+ },
+ {
+ {4356558984118475, 5693420396107718, 2518386381195401, 4410955637518553, 6067546162903212},
+ {748677842691767, 2802469894128656, 2167458034960803, 3580904381157207, 1663021749531972},
+ {672345752527423, 987721649439917, 75559353638139, 1202381658061142, 2218885179346238},
+ },
+ {
+ {4510531718276206, 5025970311617705, 4298550255570023, 4702464919238073, 3154067300975759},
+ {874026063340854, 581394977884979, 2805876061084699, 3945101577343195, 1873084195329207},
+ {262642087469467, 394043452244726, 1877384193205089, 135064540003798, 932774458922892},
+ },
+ {
+ {3677176615657209, 5004677940509387, 5802006239792640, 4988806137854665, 3142553109499622},
+ {2906530412387425, 538942497799423, 3006485045211118, 2701192894331127, 1774793046411044},
+ {2163097510860120, 1657639324428092, 324536800194710, 2127826550215010, 1492179302504548},
+ },
+ {
+ {4271383757866077, 5161359851331481, 4409665194889791, 3535427764785290, 4743868535366280},
+ {2870306695118697, 854883599481521, 1175220622088095, 2190379234235038, 2693308800279672},
+ {1469265779048270, 1543845332050728, 2202017995300452, 1928013995331013, 1762032763505452},
+ },
+ {
+ {4636656908840010, 5500309513430418, 4897834655713547, 3941193903783821, 4553608952670061},
+ {4333916659134460, 1850388591545996, 3627944035206357, 918659547384777, 3374247281351833},
+ {2000039510485295, 1183834045401091, 1338556774925931, 1549179790309018, 394428288927656},
+ },
+ },
+ {
+ {
+ {3733446780128548, 4970314905751830, 6278139198254466, 4792154002496454, 5723581693713173},
+ {1185838263017942, 1658025814770644, 2664414501602854, 2015508295646822, 2967017530049915},
+ {1569664128884381, 407663338845983, 2002256010544711, 671085899312035, 984282527793076},
+ },
+ {
+ {6341328981945826, 6310526850187699, 3023871274454732, 5578860681574207, 4775900505114104},
+ {2574316560560394, 2331223963461233, 2542672004494602, 3174853647927431, 3104624426621216},
+ {946711433665760, 2239987349934557, 803861660898522, 2156551410386926, 1502787654920122},
+ },
+ {
+ {5437578969471140, 5951179206758851, 5248530961634439, 6426502251854756, 4209704034918088},
+ {1002763931894790, 2216555692070697, 3344391891538061, 2095372815347836, 831620519830306},
+ {2050669866355306, 2190774465449013, 2058969733807763, 270320273862327, 1870514939355617},
+ },
+ {
+ {5155857617776227, 4397988213497465, 3243709928117524, 5944645730694783, 4773063750957235},
+ {1975814150439887, 3149875793027583, 1261444197722906, 2760429640974761, 1552966352555279},
+ {1633514016507671, 758793436105214, 1666766843388618, 1223902548045585, 233185566290059},
+ },
+ {
+ {6335824036525539, 5936753389140468, 4473577463180534, 4906816011267918, 4087654058111774},
+ {2368975804221909, 2457041955704880, 3876216785098924, 563819279426048, 3675362390258876},
+ {2039348563488973, 248927546652694, 729506739622176, 397171022735714, 1644628056647629},
+ },
+ {
+ {5425812761915260, 3810529789490661, 5049333453822998, 4123755530302819, 5615639585264776},
+ {2534643198043490, 3071062759450233, 3687767943508924, 594097030236781, 2123224284522922},
+ {1869384197190792, 1569592234203114, 2196362163965849, 1717386471659459, 39685498183014},
+ },
+ {
+ {4635535175474129, 4605530976221652, 3458801108619450, 4871255059096226, 3508659268324931},
+ {1421109370612225, 2276342051030278, 1620731107586926, 2516053916114754, 1357365806509465},
+ {985026127753438, 120648499984234, 3776067837201, 1121956503069595, 1317952564469757},
+ },
+ {
+ {4522971017836409, 4687828520937668, 5703673191623277, 2940799383081666, 2787006346014769},
+ {339460334667999, 3256039500082500, 1203428024902643, 1634973881827916, 2329743371713673},
+ {1781496335107774, 734939096367772, 1979958937781877, 860043149833798, 2198713547814584},
+ },
+ {
+ {4721820132212972, 5501981664895244, 5264058468541187, 3740873078980979, 5716647821232484},
+ {4072332661836284, 1169250173411574, 2007338871529421, 2541018716077961, 3008200101154560},
+ {1725071616252177, 449990873352396, 128827658985361, 673241280853224, 751856515144447},
+ },
+ {
+ {3453037913720095, 3978754968490530, 3848210473954340, 4246376002566406, 5322220851863886},
+ {2584349971388389, 535927716206948, 1961578137923504, 2896060138321356, 2010651373680674},
+ {1156080784099315, 481555143811545, 967562545637573, 1677675896966263, 907265960192535},
+ },
+ {
+ {4332897500521172, 5216833051048471, 3346087018588415, 4384949392542339, 3375716091409272},
+ {3883496497463828, 2136509343818925, 2434189290622529, 429179343434029, 2077816145810058},
+ {1658461349569569, 1605536581882396, 1366404149694713, 1196969327840593, 1143971682907018},
+ },
+ {
+ {5400721311066691, 4902133966014442, 5147618958116264, 4262202967114947, 5920636443351740},
+ {3544460334984043, 1818177095892812, 1745908205006280, 4216608321683323, 1892854460405668},
+ {665225119661694, 619309150141627, 1122802004923883, 2010090924812740, 381608939276442},
+ },
+ {
+ {3196661699712892, 3684791960878407, 5290400087132528, 4583612441617304, 4269495094598113},
+ {1614570977912342, 1623735166790269, 2524803999133080, 2496475358487958, 1935280705616725},
+ {1092465046248360, 2063398303783148, 1002343547076250, 391684155494682, 1710560533943348},
+ },
+ {
+ {4070608883224340, 3070202986942604, 4904606928783937, 3666937738681094, 5479190180948687},
+ {535566969681230, 1737993760203276, 701172348317595, 1733855888978568, 2134615712849277},
+ {606893040022944, 2129386574985473, 1699765919891957, 528478848080626, 79217852843510},
+ },
+ {
+ {2896556608610982, 6055695907875122, 3732440132349395, 5309166170174244, 2721831575240156},
+ {2885737548308128, 2508747900193688, 3606366888469287, 2465312058009042, 1828731582217566},
+ {1349811289350391, 1890659682051631, 851360755267261, 2227128394068535, 1024384097528052},
+ },
+ },
+ {
+ {
+ {4787547620178774, 3158654330243465, 4256768153665325, 5186246574371168, 4755687815664005},
+ {997854281022512, 2623211910140591, 385221936050651, 1659016544729114, 609442868038809},
+ {1619428378651736, 1579845830028655, 3625310117685, 170605089295866, 1149673757755609},
+ },
+ {
+ {3771360214195724, 3008816652878868, 5465610693671022, 3583291267492728, 4869891036079898},
+ {1431189333362726, 2522236815322768, 1841157954619916, 2384464325206820, 2357706544622962},
+ {437646608465794, 2094793895484999, 1468162389698058, 248477625893392, 1999708435919408},
+ },
+ {
+ {3334695520371433, 3812203917821368, 4517495595943886, 3819008971940261, 3192333158392848},
+ {2403562525071701, 3731091650393632, 28706304084430, 2945476990326655, 1695373042660190},
+ {11430723322929, 1391830113841252, 1337273140327877, 418617211527096, 2156223821909844},
+ },
+ {
+ {3474862062180912, 3882457043015231, 4997421855422554, 3623087331366693, 3980925476191710},
+ {2057796043232644, 2263408613360807, 3848582899143280, 1729533403820747, 3162991736601526},
+ {43999776827657, 989331901442862, 147120313740048, 495021300047603, 2007031690017476},
+ },
+ {
+ {4569310600539567, 3932567990833912, 3385323568255113, 4454797311017655, 5850805500278008},
+ {166834800897807, 3648978260893606, 1512008134852981, 3519745367019255, 2891621521405984},
+ {1308871835809784, 2116706717414875, 56029465436904, 467188187972025, 1826981082270550},
+ },
+ {
+ {4470097619807732, 4636615835029003, 5384758368025606, 3313145881106330, 4330528852662105},
+ {1956939819397260, 3815569263781231, 1153022458216286, 2428547349977954, 223633771534995},
+ {277297371046776, 1016671322777094, 1912173712739697, 1941234701885292, 1286651577841525},
+ },
+ {
+ {5516226444917799, 3864412772019280, 3317545876897683, 3844965839466476, 3985391436490214},
+ {2680601238774939, 761018381922150, 3233893633186507, 710728397015564, 1856525231801054},
+ {634704084825404, 2129536576841980, 1242863233687290, 1573321106629022, 128474589505663},
+ },
+ {
+ {4461600283819019, 5688762331492453, 3571771069068464, 3623234953171514, 5735065250408243},
+ {129496500081781, 1790297098324227, 1302842166366374, 1122296729486616, 3168849968185895},
+ {627678063257079, 716314893721428, 1223825394014331, 504272345435927, 1599415310067837},
+ },
+ {
+ {4497146074973338, 4258524581640411, 3327175345569250, 2988994176227077, 5267912111147682},
+ {1802641032705090, 1392499306540523, 1496089620367494, 2312128812044035, 3539470476015736},
+ {1352081061607517, 1142882484908029, 664622054563474, 278618602320570, 1557574337895879},
+ },
+ {
+ {6186532378029907, 2657902210141327, 3418543318248038, 4786173749208350, 3954647920849896},
+ {2160964425547565, 2522131549551103, 2469825005211132, 304256310615628, 1406273379451890},
+ {66232156124863, 1741674194899368, 1229742843930407, 260078220485178, 2065725536502563},
+ },
+ {
+ {4851046938453980, 3469458552849808, 4088972952218884, 2434262635154865, 5173422452060032},
+ {2864583883600790, 1179256560411448, 605392730024768, 2131319985409857, 1797303368136290},
+ {1658701641668087, 42705500105455, 1620862321227524, 1064411845535234, 1929505696020986},
+ },
+ {
+ {4163795150867629, 5312083389544253, 5442631052553893, 4817195733891862, 3463190319377281},
+ {1759675286353623, 1663207329829539, 2312695704742071, 376287419379108, 3196993252356633},
+ {1986557906737275, 810826505070108, 96017120328357, 1696299441261906, 1606104856145766},
+ },
+ {
+ {3549586047215341, 4636877962062236, 3055155796794642, 2987219577785020, 3528907845687172},
+ {3376650841822935, 1032192126856158, 2069071282143034, 2845533170222998, 2607538492640606},
+ {1660552858343061, 1231765925349274, 796446050473330, 1786065193241069, 1494189638115097},
+ },
+ {
+ {4395801598993052, 5237162742484602, 4130001086185514, 4318996219007855, 6361901289989183},
+ {2175013070553356, 3320762044970614, 1143129099999600, 1532959129324381, 2553098860474181},
+ {745372522040276, 1748456103797955, 2181743850112213, 796241938657904, 1942989014453742},
+ },
+ {
+ {4940563260328687, 3680309631021837, 5780417720128217, 4290252794057113, 4860748118629541},
+ {1446945700457117, 3425847613673611, 1973622627786407, 1807324498582473, 848150045623407},
+ {1097351026844646, 982517101132756, 149747537095472, 442788546176214, 1331800448358921},
+ },
+ },
+ {
+ {
+ {3048999410076971, 3892379313272499, 4501182485180276, 6013415726786911, 3538900302869245},
+ {1912748982362695, 3472588964406961, 2955977531735648, 2975418449611955, 1539793845278547},
+ {2120957025321772, 1416788979770990, 1248163529640000, 1057479098339217, 1345904049070916},
+ },
+ {
+ {4595431001667912, 3778027149812221, 3607566563474045, 5108294493186449, 4683353521871733},
+ {1020723204932740, 3177502390904871, 993238884888759, 1734688533140183, 2122148469059677},
+ {1672839208916523, 1716495024680343, 1707076061183264, 765180466790910, 2017432747304428},
+ },
+ {
+ {4097011095397840, 4818396343707634, 3336533547899513, 4282281512848069, 4911825398741721},
+ {2414052521429936, 1593372837632108, 2670905511225157, 3908207528779377, 2363908827003723},
+ {192171151121229, 1275967732855104, 1864584199775891, 1693406950762857, 451756333138903},
+ },
+ {
+ {4727218507536765, 6731370918172898, 4514881522289443, 4346751476412392, 5345399511692591},
+ {1612422054090625, 2236845889213344, 2363747608937251, 1594023725720586, 2961152477238633},
+ {1485832258557624, 680071864680695, 1288498699771584, 258483455916573, 1782424270254224},
+ },
+ {
+ {4145911876469356, 3824464555215015, 4696287494265278, 5681915693477289, 3460241462730997},
+ {2899290323536300, 2148582833270035, 4306072922611340, 2565743726502417, 1518458853723029},
+ {1953522143805027, 882595907666496, 958109305864079, 1523427692628869, 1741273556819203},
+ },
+ {
+ {6076430972133454, 5015736489916628, 3553768171633221, 4610709058364067, 5082978176345714},
+ {2177453523879316, 3719629127010202, 1578609310805205, 3246652757763105, 1948868370865272},
+ {2160967413246114, 497546389595616, 235866284515227, 1209326819476215, 385381334474653},
+ },
+ {
+ {3922495052587829, 4494539022460083, 4247467603322628, 4394626550110741, 4540112411631648},
+ {2794088217731505, 3925821314042297, 3967932263264306, 599992304591101, 3777014795396442},
+ {2143663924692386, 1851559468934078, 1845266597269129, 477022990956902, 2179267609261901},
+ },
+ {
+ {2757964045702557, 3562399862100370, 5308617563064155, 3110477941637017, 5056214367828129},
+ {1958983221377553, 2178877734404748, 1849996731612977, 1835657059247969, 2041180109654311},
+ {724524272708234, 661221141789934, 1298795839460575, 1322772218421097, 837427426454482},
+ },
+ {
+ {4223608019735549, 5288655260236562, 4785575153888318, 4056483408937593, 3471372655277242},
+ {2219315301228611, 1125545597629890, 951081168531596, 568553052705851, 1412860720276020},
+ {1137419035579219, 1404302123897914, 70650994795979, 286534554383837, 1248950723208565},
+ },
+ {
+ {4430704978424231, 4715040112563554, 3462858870799989, 3675716202870984, 4333024567010524},
+ {142500909440961, 3483510976010918, 1633124654372333, 2818821059903848, 1198913332019644},
+ {752727997883595, 729011045815856, 344467882917129, 1083479075474047, 1987011026378575},
+ },
+ {
+ {4459355955251918, 4177516598428064, 5081135773938774, 3284517801964245, 5485650974376915},
+ {928716952855914, 4109673353080708, 989163284951296, 2771681491221325, 1739599539253359},
+ {884564007355359, 1882230710793852, 1848620432404050, 211924733371920, 1690861583639863},
+ },
+ {
+ {3370568370567081, 5191721693684414, 4210754480734108, 6164440545771688, 5649472005268314},
+ {1901455587402533, 813369714566932, 4131962295906966, 1890594180896940, 2481388378410460},
+ {226931392632329, 1641783547024066, 245880824976242, 244030597682497, 308840717750219},
+ },
+ {
+ {4699529728790440, 3682875431198511, 3687823620487174, 2935047689154352, 3634282712140374},
+ {3094491104014232, 1130377028133465, 857472228100160, 2846610482750732, 1997728196650988},
+ {832395901935430, 2063621809284227, 195191804737031, 1295260648818684, 140470149874586},
+ },
+ {
+ {3598626358333843, 5555876347138442, 3551001516031801, 5418563562930746, 3796685043861386},
+ {1119383319424479, 3370445532080284, 2202737095147899, 2643552313073446, 2526474007824020},
+ {436475423231066, 206987015606375, 214066996087725, 524361410769522, 1866248992304042},
+ },
+ {
+ {5215692725695751, 3669441050652411, 4674665916750844, 5316221279699436, 6443632653069401},
+ {1081002530185607, 2909820960350251, 3592240835659126, 2824950488355670, 2408518769691813},
+ {2202470261312694, 1511198785606944, 1434711629178163, 1742102768767586, 1282697956395292},
+ },
+ },
+ {
+ {
+ {5324690866715337, 5533327845613105, 4036930034597607, 4638490931056674, 5650412235017737},
+ {1638260469631915, 1786040878698661, 3158389239420729, 3835314628196980, 2413700758553481},
+ {960395712488566, 1090263312831733, 1493488072165035, 718337273853885, 140550395520083},
+ },
+ {
+ {4569832948050874, 4985100205291785, 3844846206585447, 3819690642434847, 2746468303866686},
+ {2833809135953840, 3714738963129863, 1699035707213511, 1260336843200283, 2274544359656356},
+ {447501697246828, 643764017641830, 598739660833153, 477276555234445, 722964385617133},
+ },
+ {
+ {5743873914285031, 3319094314541157, 4059899116934908, 4330486197588569, 3357811959011823},
+ {1468688697571051, 2930932730830707, 2981359468083280, 2467829883996923, 1572642054261959},
+ {601523810297856, 895074627148937, 773977692709653, 1905383167427875, 1540507530397039},
+ },
+ {
+ {2901461178567113, 4994292130181829, 3331309663039004, 5793381747506001, 5040143301404956},
+ {2651347872114579, 1239727848347325, 3161955024122276, 2712053429837225, 3725184595174532},
+ {1148448246837183, 1915539016170074, 727268432049334, 838952046766961, 1100979659516489},
+ },
+ {
+ {4313788896597005, 3731391587318928, 5481675874227619, 5342116794928851, 4858074158134343},
+ {2801484252789311, 1308243333207398, 3101163188310017, 2902551501956635, 1782136170508091},
+ {1354449553272043, 1085110494903468, 2224048655022783, 1932600057639272, 200912869737304},
+ },
+ {
+ {3988802802744946, 3054267513827163, 5506469409446024, 5207893419318903, 6705457585999423},
+ {768379161979176, 2950328772092937, 1384131174334606, 2825110025249585, 2256845801064479},
+ {1328818899805024, 1356396048253838, 60665341223248, 1567700157316511, 290562887661571},
+ },
+ {
+ {4789838652012215, 4990599721334973, 5868836171113556, 5456092296292492, 4808665632941719},
+ {2083771618977947, 3859777942731437, 1586868936731178, 2520556279463752, 2196980677006699},
+ {1179288489475667, 394266093483806, 2023843107238627, 906600297586329, 1987935808498095},
+ },
+ {
+ {4852377011852760, 4268226436451965, 5725799343439052, 4170083215192005, 4497273560337215},
+ {2190648163527070, 1182302286459911, 1698709705179966, 2858053760026903, 512030280417031},
+ {1766029976663583, 578113072554872, 1407762358462124, 1251410333318914, 1519685697291309},
+ },
+ {
+ {2425211004658582, 3219329122771349, 4160786304284559, 4915538208049169, 4859858046454066},
+ {2165465146173096, 1900611060212209, 1042730545588351, 2014093929109019, 1810920073473014},
+ {2188210814895132, 862494540176239, 429026747909695, 420692388686242, 398456856483386},
+ },
+ {
+ {5384113697440972, 4249326538414056, 3736088109548391, 4776181701890428, 4340637335144904},
+ {2182481135659358, 1214620204337280, 1322637461359405, 3608648111407434, 919105498759084},
+ {825616994407031, 220978982016139, 419943662189285, 2047052177976116, 183513451940769},
+ },
+ {
+ {4383853436467396, 5616868348446865, 2380427384672103, 4007620388627955, 4745758889436972},
+ {3034925520134716, 2558549339328923, 2273570634299175, 2355590727329921, 1721435535499274},
+ {397259122369220, 1632965024772390, 1358524229763907, 634652123170537, 1300732316858513},
+ },
+ {
+ {4537722552642641, 4406953311574034, 4747655843802439, 4621074214609984, 4656289262373784},
+ {3211235434961971, 649442782529810, 632841582251763, 3220605671079152, 3939184634719634},
+ {596504540509310, 1411595783429460, 320205765945468, 1703829528897671, 791135694264620},
+ },
+ {
+ {3935303504608645, 5231587761610764, 4492307054736833, 4099267906214233, 3895141043651931},
+ {2905973217158121, 3180461607923868, 3881652820548741, 1616810006326533, 2007934577851039},
+ {1723586093910128, 42167711405468, 711328489930847, 1802621686437750, 138939056743574},
+ },
+ {
+ {3535285454280039, 4143874578497438, 4378537178006869, 5183808895312002, 4029558557190188},
+ {2822051371235755, 1171790929970038, 2832133858385125, 3449345178331124, 1343246277400448},
+ {201514708798683, 714458960438240, 193526864900221, 289856941669808, 677692044183495},
+ },
+ {
+ {3390373253525299, 5571978408447513, 3881939102950573, 5664584550774172, 3541416731496846},
+ {3067220342787603, 1318716141230895, 859940092247599, 2796965663112684, 1325031219234520},
+ {520206601828502, 827736556609109, 1548115289807569, 226762337353952, 901425653289102},
+ },
+ },
+ {
+ {
+ {3876784047658153, 3427402741453803, 4260413043643610, 5364266100628625, 4512454692213601},
+ {3846988412720927, 1464526558278043, 4150028797303466, 3612037356861449, 561355623244019},
+ {427225699371050, 88989906931284, 374954954790275, 1891881595245671, 72849256625193},
+ },
+ {
+ {3916811195383628, 3630554563432754, 4990637953666720, 3851134441999325, 2556181869064802},
+ {2335839984116276, 1931214780001052, 3695690881878730, 1666635094108941, 2394874384507690},
+ {487618024041635, 1610635862259296, 1930277174961405, 2060246530132043, 471988063294585},
+ },
+ {
+ {5204676678666455, 6002573394041257, 5469218649554576, 5103810246282644, 5450232393144287},
+ {2223680929791699, 2255695602856973, 2223372744379624, 2581758136991750, 1157672051964719},
+ {1191620799152162, 584262428445493, 1654487633336816, 80589900150873, 1778885798645876},
+ },
+ {
+ {3804876885771689, 3030718867413702, 5084806164730577, 4351829583495248, 4696365675416595},
+ {3277232365416075, 1648743746278574, 2268484584766767, 347896520603034, 3388269197255745},
+ {437947250844137, 170970937295705, 294909197597269, 2210849722009323, 1802271999575202},
+ },
+ {
+ {6229784974313861, 4445187233108198, 4141897661886957, 4112739300676286, 4973450766687119},
+ {2452873695124259, 3183518466635188, 3225011157480339, 1530254508436786, 2236389510678133},
+ {1718640585909930, 289464657861405, 256448940553760, 1840710967168708, 1367355358576031},
+ },
+ {
+ {4418094237484866, 3862166158397851, 6312584233293658, 4170168684472692, 3205101920356659},
+ {845231506816104, 3749601727822635, 2431461776355856, 2145415545771870, 1633953832787249},
+ {1855071951306216, 234835319416374, 608676288546844, 311106921331784, 1424607004261872},
+ },
+ {
+ {5534887235292980, 4955913319898744, 4436282654044178, 5157071574798331, 5799145956361697},
+ {3127590738217404, 2607909890139434, 625984861031328, 898713331800149, 1867577233264451},
+ {865238419718368, 2167660602098967, 849033435333870, 1879862001988212, 2194604163295964},
+ },
+ {
+ {5028901701646599, 4744711118820448, 3470202116031185, 5070974802044518, 5029459282472967},
+ {2597573876967117, 3500480183251406, 3245567533116125, 2884144221342044, 2745802723161587},
+ {1262037831799441, 1761445988918060, 1818282615037362, 643977010061831, 1670449776207217},
+ },
+ {
+ {3900064283125076, 2932367474353790, 3722342375883231, 3973709010425436, 4168589452466075},
+ {1182011269637170, 1702301475425876, 1754593023447641, 1069325582888970, 3665084705482905},
+ {1389152123534754, 679131622889370, 1335753122628610, 2193861582528949, 1750442867995809},
+ },
+ {
+ {5195225631658915, 4626594891714746, 5530846200979591, 5835469573794033, 6108601962615813},
+ {2118803625617181, 1938389959549060, 3158628651247723, 2603939933464505, 1887075807282899},
+ {1094771758119662, 1784696951595960, 1586111086846247, 1024621381632866, 1336860396265070},
+ },
+ {
+ {4962714218495987, 4686221014092595, 2854843506884281, 5460710344297905, 3609844163230280},
+ {3350136365379549, 514082045997139, 1809601258343901, 1359082981819817, 2325132321451910},
+ {816435505147956, 959029754172122, 1905562189095432, 809602990954940, 205405869295},
+ },
+ {
+ {4658319919071161, 5037557822453179, 3052863244608605, 4920651274442715, 4594868309263967},
+ {2357418342397899, 1599797957446167, 1723240952262061, 1521319741808023, 1244021174200017},
+ {1682663787527018, 508342182938395, 1334960042435994, 788285033210835, 1620852797020940},
+ },
+ {
+ {4468831118271270, 5037652592706325, 3842859113890724, 5119527774959881, 6070895395223645},
+ {2858969631689118, 3774837200669161, 3030920205974308, 3569621881524763, 2272136016309579},
+ {1457792005629762, 1504843532852533, 117754270187566, 1653728802150419, 956441650806976},
+ },
+ {
+ {3858799123389730, 4813864196253754, 3424673118223091, 3586667532616773, 4976228037682591},
+ {1240797555104590, 3504953395544138, 2270523358088921, 1192446004554973, 1265977430218831},
+ {209033356623489, 521030133202188, 2210759687093959, 1391735568682749, 2066024683275958},
+ },
+ {
+ {4447381514683745, 3805818101586919, 5048484781457783, 3805764540626535, 4979430662961349},
+ {4372830229780273, 3385211896687553, 1322477629921689, 1744994285972241, 2453525332947167},
+ {469280089327132, 1530255390484981, 1847838662987617, 2225747405410001, 1682362262024675},
+ },
+ },
+ {
+ {
+ {4202827224002136, 3028138102214431, 3666469969152450, 2607795400549083, 3461406593763699},
+ {2143318224651032, 2985185441001099, 2506505238926850, 2498470302228395, 1442295963272081},
+ {2200224066087308, 1167051805827953, 161446888552827, 1516422365939770, 1942535836845300},
+ },
+ {
+ {5171889208942910, 4780829163437052, 5016462198638337, 6470156341077032, 3046275441821918},
+ {3482226206224520, 997104644926830, 3305574633418067, 2147764348670690, 1676514761128454},
+ {1628314393858778, 1997743320994668, 1561201521750924, 1869590045554733, 1810714681142288},
+ },
+ {
+ {4681454419314826, 3433609902051237, 2919531098016978, 4380876633130549, 3072926890864646},
+ {1675422916543594, 2672408744787477, 2759217149054666, 640362125760161, 2799605921604096},
+ {1484872832783728, 72255685107270, 1098972476164964, 1732914770170238, 145186792002379},
+ },
+ {
+ {3935383441158753, 4973709539651372, 4161806475746733, 2598419220788322, 4556716999515219},
+ {1372652207334635, 2531888280983978, 3771287204988285, 2258792327010408, 640671581341507},
+ {156581553787681, 307978851206907, 1451582278870485, 442722234791876, 662472042575165},
+ },
+ {
+ {2866740058396235, 3493635817947651, 2400937210085123, 3122677618181344, 4447500274280321},
+ {2082652078388943, 2745645971502049, 2295760696601975, 2362848920638954, 2370414183207021},
+ {1712668510139487, 784271226274642, 827073136956465, 1001465329762964, 1662630974562798},
+ },
+ {
+ {5156175574821430, 4359502037960358, 5222120068062442, 4645531980214215, 4676244221442153},
+ {818080711416948, 3611895686544640, 2535691662679364, 3086441935441805, 787978368976315},
+ {1509857525874286, 1496970584948645, 399828714647739, 1863753979948441, 2149707660031809},
+ },
+ {
+ {4144865997618639, 5339859640465925, 4438288719418715, 4715011715150674, 3610459694506906},
+ {2952195132229463, 3345568150314393, 1768906295222689, 2025477905414216, 2995593107979034},
+ {1951144383031056, 1085048452592587, 499199223423315, 2055889411465929, 698006601614245},
+ },
+ {
+ {4183964222033211, 4817865139479783, 6220809882369837, 3643181163556103, 5929569705519063},
+ {700816495675241, 1165569165048171, 2172597164236109, 1071655796287173, 2392628493878193},
+ {1862104717906915, 1752261107932084, 1874923294613947, 1008681858018398, 628821150989939},
+ },
+ {
+ {4161348428018682, 4510282473079517, 4817307873546246, 3901464805798077, 5820970885668019},
+ {2393760120508366, 2923675062487769, 3447512431195440, 3853675368087017, 2900110716170471},
+ {271735680629051, 645447398246691, 1438808971583999, 792432482423730, 947645802664175},
+ },
+ {
+ {5548911597254848, 4313111803014757, 4159094458160020, 3906456530516599, 4703406736341543},
+ {2468698810952212, 4159587806133767, 3895277333299798, 2370621230252749, 366242246574179},
+ {1891237336529861, 2200322075990278, 1389309370267760, 1284260243869154, 2019396638376055},
+ },
+ {
+ {6612681523843925, 4270864305450289, 3731318918021201, 3544862780769488, 5178202040634906},
+ {2135755065262843, 1122607271257525, 923542923082409, 2860818598984322, 1922554972749380},
+ {242471180181642, 559887731579688, 2072408437063313, 1092425853708654, 1508919031894623},
+ },
+ {
+ {5872377157668488, 4408911728296550, 4215455815151923, 4350437538061339, 4304102307657902},
+ {3016579539029836, 3430456847285690, 2439572409111001, 3210834728649259, 3775979784664836},
+ {681181014012506, 1995504690201206, 1747715035603252, 100305442172708, 1898381133318416},
+ },
+ {
+ {3131841243480282, 5236372530773376, 5021877536268058, 4866190361541948, 3290429298804025},
+ {1471590353308208, 967056793878588, 3802522075784380, 4004598771731972, 2024618065937019},
+ {1109658864423422, 2103734444560570, 2073023657041166, 369769649281723, 817132219307245},
+ },
+ {
+ {5632635968843701, 4247258704551623, 6265280169576672, 4815811703628991, 4268679712320579},
+ {2186780367255445, 4183850462668485, 2677999934662660, 2880987810780319, 4113828005081983},
+ {1441842413844030, 161967823757178, 143843657267759, 468984586211790, 1403635869302761},
+ },
+ {
+ {4465016058776751, 5317359619864273, 5237005983845137, 3609875861871372, 3464614715951065},
+ {2238448064725901, 3110619177809235, 2162294075762619, 2319911679772150, 2285011619226311},
+ {19804365830533, 1686591959644968, 641957734952114, 1534607041731245, 2021106986001419},
+ },
+ },
+ {
+ {
+ {4685063337509321, 4828498939602920, 5252037453775058, 5946493173698145, 5385655016202805},
+ {944214205150673, 2365379166371694, 3557291173836860, 2962349586178017, 1508433893219247},
+ {99837384801727, 2128746966172064, 1728087272474317, 1660968164341303, 2094478837305487},
+ },
+ {
+ {5059816654277047, 4494318859907208, 5234935703112714, 5064000806734505, 4673368238982494},
+ {1045092786794937, 922156857253434, 2823065772236182, 3280047208436923, 400144133024674},
+ {1350540322092981, 428507123444697, 863081413402232, 950089447398951, 118865435494230},
+ },
+ {
+ {4685872193140817, 2986094649249487, 3994164430284207, 4339988837278092, 5456344527489565},
+ {1863120758931529, 2615255562194237, 2546630581550601, 3581241606812888, 3495878108380709},
+ {317239144147936, 1378693805440304, 1613995646839215, 1790616997152168, 1664744641804674},
+ },
+ {
+ {5168378766438094, 5613439416641824, 4644053531787994, 3823661418550054, 4036137961950509},
+ {3162078769819650, 3145982897294820, 830213734772942, 1343060696486484, 611721765217825},
+ {220994375354681, 1633125608855915, 2233079832150828, 144297568151940, 217868145580028},
+ },
+ {
+ {6394803792754188, 6132368335021053, 5067197744306631, 5563640033331609, 3502674887523375},
+ {2185253522527390, 1722061079589371, 929518249744037, 2473172243807197, 3427214482375105},
+ {579681536856473, 1962714631533051, 518559321779053, 971489356480100, 509262501560864},
+ },
+ {
+ {3925113491817113, 2597442932750426, 4547336592857079, 3567634098715516, 4305879739481027},
+ {3780232691597615, 2387499794027268, 780855157188913, 1744928736206446, 1837149863417515},
+ {1612827416827303, 1149821613065205, 1844912308905994, 429769677786205, 1866058244678788},
+ },
+ {
+ {5323969415910835, 5007501896425241, 4051100888248418, 6293526281093731, 4819708586854638},
+ {1087967203355487, 1504313118437159, 1271975234407042, 2125305808015759, 1278369242007838},
+ {2109491846902798, 1459244188614787, 1145316246074802, 537401043713173, 2076110035136585},
+ },
+ {
+ {5420343519672736, 5167540178478133, 5227270808193702, 3857502656954627, 5090553389549522},
+ {2543056198437618, 3682981507069573, 1492922137755706, 2553269698918225, 3362719634517442},
+ {641798503068060, 129975789967638, 2167736719761015, 31631641435626, 350785183214734},
+ },
+ {
+ {5066057417347081, 4106102383764030, 4636402204189217, 3166449457097492, 6512612113974837},
+ {2326671091720579, 1608331768972414, 2153369779460415, 2214666295188594, 2144539481917009},
+ {467300109694399, 1693264194394125, 270333528447105, 650109201517682, 1183509432017698},
+ },
+ {
+ {4980219730800404, 4347683389360629, 3797217994168414, 3968193844610984, 5065496827863311},
+ {1399648064845078, 1606346276621799, 2881852436764688, 2553259795593478, 3428187511626105},
+ {301865991723133, 208252052427984, 51972802328726, 2021710333754506, 1378508945174500},
+ },
+ {
+ {3184436513057976, 3574184872992923, 3980701068825082, 5420309832432621, 4126883464345483},
+ {1378603098333140, 3238698568766207, 2846856431574260, 3096436218915115, 3811649319155499},
+ {847831302663356, 1506598425567944, 1109350264779453, 1031639907526886, 1887329321191319},
+ },
+ {
+ {2729102328832984, 5496148280158443, 4624803589574900, 4730709608222510, 6347472137270048},
+ {2243355286660512, 3259846408864417, 1913072889496856, 753019988978676, 2074854260894060},
+ {1050426720469833, 301805153257576, 1393268630450121, 1286505995795045, 1587323866723540},
+ },
+ {
+ {5177553689561919, 4133777550475335, 3692495435897478, 3458719135916346, 4458613993531757},
+ {2247714139881915, 2782180885900161, 2312112468846576, 1680267679651832, 1590058688526667},
+ {714977855392027, 2020332496651261, 1788558438911234, 1873232632822523, 503071332489421},
+ },
+ {
+ {3928537419758315, 4962617917721336, 5009684278125795, 5080330424879792, 4736452659996568},
+ {1885791717393579, 3608519904666432, 3804656767054515, 3734399316619142, 280860879781734},
+ {222453425419780, 1881231455372494, 356159674087381, 2031436073565603, 1587722788974501},
+ },
+ {
+ {5557830146603019, 3189235339941465, 4073380612031396, 4406171020530468, 3729384279482635},
+ {1262604590990019, 2611597233679237, 1167025725287256, 4282778604598424, 782190165854895},
+ {2186405536221393, 1904322539012708, 152608078674767, 560457311616919, 22952815837658},
+ },
+ },
+ {
+ {
+ {5410522905087843, 3457067311541871, 3734790664132962, 5317892036251255, 5789103873795877},
+ {1051236049852089, 3090035912523931, 3653329677163146, 3071361720175865, 1695547314615009},
+ {342012360452061, 1887029215668228, 1155449753977691, 310762800506541, 1868750527042639},
+ },
+ {
+ {6005811139638228, 5026414264668887, 4377100252408278, 4270582517957803, 3422272486715601},
+ {2698577143176842, 1182111476573107, 2613378546611642, 3220851371976805, 2803670963190147},
+ {883746203814773, 276737323512287, 2229390196673160, 2155663378443822, 635390057802745},
+ },
+ {
+ {4097156896954595, 4786624081470779, 3512858804636033, 4586748051134289, 3866073874774231},
+ {840689961188261, 2918655679606741, 2236632145763387, 553161305644429, 3021893411965909},
+ {1649953183870355, 2176771717569818, 1233096109604549, 1152511702037810, 560573824644263},
+ },
+ {
+ {3626792084314328, 3138501138424139, 5501515071454841, 3948607545905590, 5453543250308683},
+ {3279453112825750, 2682669747401601, 2291239772155005, 3644653666115630, 3532224357711467},
+ {380965098906693, 835788132761480, 2232989119976139, 2205277179143298, 1175904351372329},
+ },
+ {
+ {5088419201363648, 3175894686165450, 5299797135086175, 2983523363221301, 4220825923293130},
+ {1276840412816828, 2771169526519092, 2136012615148103, 2431893903507465, 1217611106137226},
+ {2073239372536943, 30649016949678, 644492521678981, 305840627193069, 109901429265295},
+ },
+ {
+ {5139707358045825, 4688671704193624, 4352852502302345, 6384641621021538, 3836551482242832},
+ {1192657509706017, 2505894684845872, 2556098156240875, 2309411544504528, 1820864150951982},
+ {1002466072624564, 1231676492638173, 1795061881446222, 564780581799518, 2025621015597595},
+ },
+ {
+ {4858692159454824, 3985618384769197, 4768611969748369, 3070997304216167, 4648245907091308},
+ {3367644801750200, 3754604094141859, 1751381457602879, 2418709533236081, 3882122160708146},
+ {374714050779396, 405289438859672, 1963133877676048, 2112584561135192, 1143185401022561},
+ },
+ {
+ {3846711807981435, 4505402219442327, 5146862869313170, 4623705187751987, 5565609289355471},
+ {1926650836092769, 1141267952622767, 3387976667434360, 2038056869767013, 1320936551384977},
+ {283489509389185, 614480115735096, 278795579529276, 1166609138076060, 1715497286463476},
+ },
+ {
+ {4275758633577087, 3861278996194559, 4466252217383748, 3665496078445880, 4058888268167473},
+ {3871692294074427, 1764539273907035, 2887939385751194, 2243961968498350, 871865948439469},
+ {2109468136302879, 794757759853720, 236685909745726, 1503678842333224, 2147818470882973},
+ },
+ {
+ {6104878619412512, 3485890441294438, 4220586739682332, 4017322426737508, 6001128289990864},
+ {2677372099733352, 3437936829126546, 1424452207982980, 3507913002098314, 1735468130831162},
+ {1938075620777682, 1762081466410536, 1564991344244054, 1376297777594771, 248036172502508},
+ },
+ {
+ {3778095331789531, 4910813465857036, 5137553967349467, 4984396828084641, 3687371747598377},
+ {1479550570874507, 2294055327463876, 3724831818626703, 1654245262468829, 3019040190597313},
+ {1873423061916096, 248167770548070, 903648623666602, 2087943940366473, 547940262578569},
+ },
+ {
+ {4725001988101218, 6546220549270451, 3469130078731384, 5687075187757928, 3413336519371176},
+ {1413358533598756, 2252005803690891, 1458088388485468, 1671589233622260, 1797166284473808},
+ {523276182513223, 343307024193534, 937383689926833, 1330219799726239, 2232356434433501},
+ },
+ {
+ {3569532147039540, 4195918401728545, 5115321889044388, 6609417783186476, 3958938427322120},
+ {2397395505704106, 1262743052475361, 2547892063055852, 2321536665849090, 2021113849426924},
+ {141428615990698, 1565258204511290, 2188430123291708, 1781055032390171, 763358600759749},
+ },
+ {
+ {3906824289179955, 5654339223566203, 5504976063361072, 6361176910130113, 5155227057638370},
+ {721005728190537, 2847737995575099, 3056729868442396, 2393716554993649, 3467469336561398},
+ {160800301986322, 534920738504617, 1465194074759867, 132949302971740, 1176455782582044},
+ },
+ {
+ {3433889410020031, 3665956712149865, 5366646390977683, 5367384152674927, 4795948454618784},
+ {1902504950598053, 1202752625490289, 2565725054888499, 3023474686925025, 3059561010324150},
+ {1935479944158543, 1102588664377385, 1651606970291190, 1048887489959304, 1677042940335362},
+ },
+ },
+ {
+ {
+ {3858553186233324, 4192597543704949, 4422265554716229, 5060918874051413, 4251667779718110},
+ {2960733565044348, 2107676482823115, 1657279889267301, 1609984394439769, 1082526754413784},
+ {1823622181083017, 408967151178094, 2033143529389867, 2209724434343478, 918118538477317},
+ },
+ {
+ {6088716933512995, 6116095372188681, 4275776721065459, 4475819482692536, 4685952285527508},
+ {2842268335288737, 1888183319191451, 3692488899816305, 1677336684221250, 4176880757505444},
+ {463491021439363, 1750609461077078, 1169967881279297, 474253519600450, 901070375860211},
+ },
+ {
+ {4400692422952866, 4659690717529996, 4722795303748102, 4016471577087528, 3702653606869112},
+ {3485976485792634, 1118156106770038, 3653108520059592, 2301046652704138, 2381698882921202},
+ {288029433804634, 1918327772711516, 1858109617364668, 1548745667412753, 1635036158704975},
+ },
+ {
+ {4899918186072737, 5587073618198231, 5408433162977742, 4217274871182020, 3058703542950255},
+ {1915560744141461, 3219944346867669, 1684794323668364, 813038486884416, 2736974530406253},
+ {131383425958682, 1726194406199626, 1195125520329959, 1269440178344704, 1934708138886976},
+ },
+ {
+ {2560939345231273, 4301322442066007, 4073130192422468, 4440850393019204, 4883344655404735},
+ {2185121667669569, 1115206785572251, 704158439711004, 2133851508118048, 1251130304627637},
+ {1895230235031468, 1896812472261458, 768470747222158, 1996242383935516, 1420798451369434},
+ },
+ {
+ {5839795121226482, 2867951589507385, 4636256264448023, 3052659764389740, 5026931603960818},
+ {1579856931436900, 2447051767839229, 2868067823655589, 1688893962924788, 2116170079089324},
+ {556211501812000, 449190026847667, 2036295767110360, 128995208617458, 1118467502984960},
+ },
+ {
+ {5602461071232607, 3307918487728174, 2854017338064603, 5855272157497266, 6150895900635822},
+ {3398390622800229, 1820230761045332, 2690748155578623, 3095835968664066, 2530217218349662},
+ {1878982227582804, 1431346083601994, 1534977024077189, 2155113334662581, 1782950372830762},
+ },
+ {
+ {4697661970186985, 3763132135142867, 5033467660349912, 2907155321697052, 4660465007863417},
+ {2604312744349849, 2452708102821815, 3230466926286856, 2118488738947708, 2304478471957885},
+ {1390885694073460, 1816639772663275, 1066627353945560, 1454561122724455, 848860562366790},
+ },
+ {
+ {5540829116940004, 3948748499449809, 5260550454870879, 4676389564943908, 4383546683050662},
+ {2563789831020858, 3343718595008637, 2259025389677919, 1392665428080842, 3671467539073936},
+ {981545110828877, 510698765880228, 2161678679515528, 1436791773758609, 1673597748298096},
+ },
+ {
+ {4329713062953095, 4939339976361997, 4958702235647932, 3268883154176961, 6391544885910171},
+ {3614223297666549, 3897390208178715, 2811994039134574, 2958689501074087, 2363866533687133},
+ {1294858674770242, 529668890256843, 2030539078163824, 294693146073477, 969527805905143},
+ },
+ {
+ {4670371383742225, 4002936514889177, 4966859846610707, 4736741110602146, 4760957427324248},
+ {1176127152490445, 1894013131106171, 1812632908007715, 3751034747324574, 2289873378487758},
+ {61868149975749, 236120696290007, 608351327055311, 1829919587421069, 1627340269896729},
+ },
+ {
+ {5062259960708944, 2689430826280744, 4108030288846956, 3316359330121699, 5641758926485313},
+ {3722896082959268, 1863222026681564, 2044934869352810, 1385880696113195, 1308481967864035},
+ {1796753889379582, 2232245583163596, 176790521107364, 133826841897595, 1041041183235991},
+ },
+ {
+ {3537934576014922, 2998428847270897, 5788967881664907, 4283416153137820, 3545722873501844},
+ {3424639235617092, 2530506041245943, 3202402279176211, 1867524240141886, 1078908361802522},
+ {1442655471934418, 1764674447040318, 316317796980033, 318184491515700, 1168933061547497},
+ },
+ {
+ {3599845082833499, 3896846545871592, 4303714095196951, 4532827504261802, 6020561742040974},
+ {1580156396502051, 3208244370687690, 223926404960589, 565074765027696, 2169726994764050},
+ {1942280341359651, 50425926664281, 1816034234875212, 880607828368837, 2092912650330571},
+ },
+ {
+ {5512765861463031, 4125716632501591, 4924530697112776, 5238255918415337, 3653602071478327},
+ {1344167653424867, 1048535312223495, 1948741777806718, 3072730820612467, 1645288196866883},
+ {1745152490874503, 1836336442271605, 2042898833391948, 1540893062903555, 1183365031475960},
+ },
+ },
+ {
+ {
+ {5866266958495514, 5059063420853561, 4485040531648720, 3733835905319672, 3149359201467933},
+ {2684460961013652, 3709949712072759, 1783966662497692, 1338383483986408, 1938129546538183},
+ {40033251972751, 73885946378640, 1935473366247146, 1461619709267546, 1211799649582059},
+ },
+ {
+ {5250457209059169, 6625476149991574, 2830402208757038, 2943786524207392, 4303078760549837},
+ {2301225069080269, 2184860938031358, 2273332051328548, 1704804667098002, 1911735781256473},
+ {2217303387266656, 2227853943602075, 1384266551040407, 847818056628355, 1874126181291960},
+ },
+ {
+ {5228171959238562, 2572808713483427, 4818692310321808, 3983994866935258, 3614639592657195},
+ {2763608237796206, 2346801614322209, 3045306834104040, 1893958852943478, 1490859261541415},
+ {247688480299164, 1512873113726713, 1351630747308477, 937439467136054, 1030677695284257},
+ },
+ {
+ {3673708668048072, 4665314801263177, 6233349558231934, 6339984458236183, 4552548914816150},
+ {3247306673138258, 2425869243107473, 2622484905091774, 2040657700179409, 1450858492090282},
+ {1636572211186580, 2000987144770729, 1893417472062746, 196779160527558, 1557344243161357},
+ },
+ {
+ {6493926578942193, 4543542057302668, 3472731731448002, 3629201377772109, 5141975006754257},
+ {2310006248725699, 1647962485872618, 2823143389536034, 2192050419207497, 1818655878772515},
+ {1024434193686880, 2242250021719251, 564307645117404, 690001361734624, 239056809198959},
+ },
+ {
+ {4713019913612655, 4128228433667681, 5028024885108113, 5705734794679268, 3306562584580656},
+ {3717108646348257, 4084515682195001, 3812051722646527, 1684888211341314, 1618372056987552},
+ {1877409538331051, 337692456674055, 879114692044355, 2186377676371749, 1343387843321657},
+ },
+ {
+ {4142192651183813, 3524721259616285, 3594705099270661, 3959153982160586, 5413021910706886},
+ {3669516570196207, 2121969005742829, 1652467606544375, 2698034847882520, 3275951535145684},
+ {535664786267626, 858000264335400, 1392803193793530, 460772165692459, 1244185301942167},
+ },
+ {
+ {4502106313596470, 6443346829525378, 5721231993875900, 4681113914034302, 5472479613319256},
+ {1495731174651276, 2532746921337410, 2156800382632014, 1987445924091844, 3448117379338544},
+ {483117633444291, 1721449975252800, 2014677970681898, 2079902425951169, 117285229800651},
+ },
+ {
+ {3261832527463430, 3508653912421559, 5988429677058390, 5333822038484553, 3271080652355482},
+ {2204547407113574, 2042779888674267, 2424936780736806, 1416144793524967, 2647730853119196},
+ {417006946097712, 816142170165382, 321665320486095, 1120596382678137, 995334532083163},
+ },
+ {
+ {5667435300952982, 4583050105149113, 3937627982933697, 2917941244133350, 3746324610420174},
+ {1654154218632292, 2424649854522191, 2118483268871125, 2658103876978958, 3351121693690514},
+ {1757087236610187, 114932695265885, 1498710897730185, 1732388966595209, 145995973897689},
+ },
+ {
+ {3747574781762871, 3444173068370155, 2989065545095348, 5144077823603124, 5597474176298234},
+ {808058917355435, 1642072317689253, 1764756051109168, 1619463984060522, 2971052737331444},
+ {344784500521841, 753070981245028, 1021287645349333, 896645545453199, 449568974542070},
+ },
+ {
+ {5037125630216086, 4317087092146610, 4394758621519137, 3169411347551391, 3200762148534134},
+ {3758879149962654, 2267958484085658, 725842773817223, 2203610500470887, 1640888914156664},
+ {1753063336824455, 1632699439142352, 654655992711894, 254878945844677, 1142235737877277},
+ },
+ {
+ {3668977677139265, 4332641682100108, 3590347451295966, 5242849066395039, 2727116665213341},
+ {3248235630095651, 1380466035309490, 1790683862609512, 3542725848725101, 2663722245169429},
+ {863640852068414, 1530602868551714, 1707160942886152, 54230982937714, 122819573759751},
+ },
+ {
+ {5532810941110268, 4585437113624970, 5116705204102219, 3665108856301161, 3445572551989045},
+ {2829139259902194, 3388923696568854, 2569841942150467, 2697982670988693, 2163914772008849},
+ {2076653457069888, 1193685867720358, 1325584969753937, 1501472994346955, 87079528165998},
+ },
+ {
+ {4556025881223574, 5720430347742651, 6074363308505144, 4027406626756934, 2527767620430889},
+ {2142131119871606, 2984501701896371, 2717746191530066, 2203225891573820, 2175517225379719},
+ {897107227346093, 455907621058237, 864390863340574, 316655721359786, 1688391871841069},
+ },
+ },
+ {
+ {
+ {5225107848603314, 3997985175873023, 2901647838494787, 3895284350008311, 5682946636557185},
+ {3523031484358436, 2824636666213863, 2395141832526945, 770528850757883, 2501907940021781},
+ {722866669050453, 648025000876863, 272387785321835, 1191578896340587, 133025146298323},
+ },
+ {
+ {4430018927628058, 5528149113975034, 3884602704599257, 4041974594447505, 3905022194274965},
+ {82857304500618, 1554338034359360, 760468202446199, 2344834461467455, 688719719651551},
+ {2128452325542740, 952454207454828, 1516099560539414, 1362377470631451, 1181280467630705},
+ },
+ {
+ {3877905624740973, 5612025444592814, 3620377076227448, 3557624466809644, 5794884625077990},
+ {1234316951156125, 2774803744202148, 3038336850143346, 2839603046584234, 1645722164542234},
+ {894237486099210, 1516039905189318, 1740044048087400, 593444525063043, 2109764897178862},
+ },
+ {
+ {3625360958175610, 5708422748846073, 3787265901576189, 6157656721094708, 5961588011087405},
+ {1482109974932762, 1512691293799179, 3308418655922299, 1669766513116242, 1645628848588889},
+ {134048702591674, 1512942576919112, 1666722043826583, 1830910766776036, 90483195207340},
+ },
+ {
+ {3762249153136541, 5419647444574112, 5020263484993746, 3697437793067561, 3831953348456062},
+ {2494438010166937, 1432383122970498, 3625127628421620, 1764585753875763, 2715866922646858},
+ {914153294895020, 1485178337004016, 1172992438642136, 742396957515979, 1460451697085215},
+ },
+ {
+ {3293341585462216, 4914585647995248, 3425647660888775, 3851476795826281, 2935952374714235},
+ {2881676317687314, 3127597808111770, 1680974550469383, 2631492786928655, 2080467460645229},
+ {1084836891982052, 405373371974756, 392292573225522, 1228291428535054, 196706224397467},
+ },
+ {
+ {5422966393229312, 3517798661028565, 3491057102408135, 5349612585124235, 5098313025804708},
+ {2181085219797570, 2438267619893703, 1398091257339579, 1543623638852333, 2275879750497956},
+ {1451708073273912, 640663458576442, 472967005176057, 1940369909273489, 1650816055376110},
+ },
+ {
+ {5775591770146864, 4809727687563635, 4066767569195787, 3927850608944429, 5542524111957037},
+ {2856057239056516, 3899713821492127, 1178627125851433, 3276833765573271, 1528786153297881},
+ {1406590024268518, 1220852036090080, 364949301397175, 1654716393716139, 143122595639438},
+ },
+ {
+ {3092682960222618, 5760168522994174, 4966136799494047, 6183321071200806, 5955160799299141},
+ {1679800253914106, 1418780742199926, 3419507991072325, 2296436046846462, 2072736467396911},
+ {882943817583285, 484844826182032, 423720125645701, 79705330082926, 518433021584838},
+ },
+ {
+ {4303808439591566, 4492049110308958, 5005208589399660, 3449528090765045, 3218284505011813},
+ {3283940803229324, 4459508559485836, 940189907838090, 1705424518756533, 2039165337931945},
+ {892563649969864, 218618659831677, 483384434921296, 1959503286788495, 846111377588119},
+ },
+ {
+ {3736052427633640, 3240841928280071, 4678563487154791, 3752373267871112, 4181937274986806},
+ {2003615224309886, 1453829786196949, 4170849260029473, 2196915936737576, 3465659437703250},
+ {870814358129174, 1509533025339595, 2053081266530331, 1737753718216259, 77875205064950},
+ },
+ {
+ {6295693526685959, 4477016414498074, 4045516627237016, 5610462754780940, 5285590675711912},
+ {2091650387347437, 4186999032385018, 3695680781345242, 1318896896580492, 3133525015024966},
+ {2057751622403208, 2124826136415213, 2162400122701924, 512312961318735, 2072953190856236},
+ },
+ {
+ {3421075047723659, 5902999844007244, 5257660560322253, 4411230485782045, 3851018473810833},
+ {1356912041975431, 2088651341684568, 2115599337938785, 4037573216393849, 2652908467965391},
+ {356251628924273, 2088769627568139, 187882754343055, 394347310503797, 1449630398452630},
+ },
+ {
+ {3682820885194585, 5173915763318849, 2521868910298419, 4165015930825951, 4883528324075009},
+ {1067127578201981, 2883441503009643, 2032675011298617, 3963320928045487, 1183903438950389},
+ {1431421126152216, 738544074023370, 2193830823196529, 1671561335663722, 717735409657132},
+ },
+ {
+ {4201586389811353, 4375880219104829, 4192199017276052, 4416844421544609, 3903714904213483},
+ {1449584304781523, 3077329128471461, 2135282471631868, 3283981709093825, 2025731372310411},
+ {1183319077995597, 1294226945214786, 1175504892926680, 1065468559536653, 2201437139069262},
+ },
+ },
+ {
+ {
+ {3505559764260479, 6013086951275753, 5081911139396344, 4716516055339902, 4005184608137658},
+ {1941635877650331, 2292936607701027, 802548087270426, 553714331402352, 2637835706093694},
+ {1415499622184076, 11739232724558, 1448526577403933, 77973485783393, 148463223858677},
+ },
+ {
+ {3556556070469100, 6104580777770606, 3153395731542438, 4746347503688425, 3530835687615003},
+ {2563241728545350, 2900457320970642, 2021653799300720, 4081786454058715, 1684057546885165},
+ {531432570362576, 1071513573823369, 449672118652203, 98547521251379, 260579416510065},
+ },
+ {
+ {3113402949202118, 3224343282781895, 6393340053990193, 4574021187583530, 4354743893457091},
+ {2098297300858722, 1637995723173513, 2132191683177015, 592134746032938, 1044637126699087},
+ {607038018090674, 1768950085932612, 1176147243379098, 1239851308662055, 1164850159859507},
+ },
+ {
+ {6544624144736846, 3158440120316048, 4122467747600782, 3270454787206357, 5173743677397902},
+ {2302101840952822, 2675605826160506, 3431414289057246, 2525090851992001, 1591101869035052},
+ {67986117053250, 143032219413988, 187059126532888, 1606721935579222, 2108737133289470},
+ },
+ {
+ {5726022544095362, 3724045113988627, 3515582956648241, 4176155101637246, 5525745188146662},
+ {1710358734492362, 2952544254120043, 2348808532032187, 3458396516769880, 1537007452608630},
+ {63942543002426, 322070337950512, 1601643046070686, 1223905889282175, 1741111665223434},
+ },
+ {
+ {5315895417052113, 4828375526334729, 4444010786735381, 5993309905616190, 3640401138113649},
+ {2860407040121293, 1177142915116463, 3145140653940871, 1733521080031482, 3186874796199337},
+ {731527977617797, 464892677638406, 850380242165564, 1707297435867315, 797914062581028},
+ },
+ {
+ {4481445847621310, 4194775426039896, 4717484155432068, 3203129625283069, 3774741254649070},
+ {2200385186612512, 3830080434695126, 3332312936597714, 1819075993402941, 3697021137208346},
+ {1808087344592199, 1917986815291197, 1736625562156353, 1691009053422774, 699554104203468},
+ },
+ {
+ {5048623459093582, 3345582890430421, 3965077987869649, 4640623371578895, 4912032720993151},
+ {2302864341793270, 2363316925891845, 1559429527589511, 2124275860379685, 1685170275648173},
+ {567087552892581, 1562927351866469, 299640978917608, 868196882482839, 81953139898216},
+ },
+ {
+ {4967323480101032, 4012272011745302, 3862894427518599, 4308636686245327, 5217499651112315},
+ {1252667495912574, 926763760798846, 829943705996489, 1227324880932263, 964621170655609},
+ {955876088496614, 2071382636271538, 1339562676294470, 1915921082315197, 857114822306108},
+ },
+ {
+ {3257326910061677, 5127439013196396, 4310630254544639, 4686443315427179, 4724730249377907},
+ {2936128018106963, 1695470026893168, 2973127512604355, 1666309508011309, 2226049713730899},
+ {1512722216346670, 113316334999619, 1851114541854723, 1700671412068281, 1858477808352196},
+ },
+ {
+ {5998097796107191, 4771418173207581, 4274779313964863, 6374384720876343, 3691059377431806},
+ {1747059722842985, 1151985779666741, 2579873034214805, 2259025270175461, 1104167228907676},
+ {1120011747324768, 1881628887342023, 2214290331844435, 486356580332714, 2162135539567334},
+ },
+ {
+ {5415017211564966, 4131956504736867, 4606393482137328, 4786286211324892, 4752001899018321},
+ {3516707084985218, 3646421870194647, 1944208348735794, 2748388507091938, 2933933255585587},
+ {939102610898658, 657762889309704, 1555084457788919, 1150153333777593, 1006706590082496},
+ },
+ {
+ {3543688234603472, 4194712450230855, 3880927772745797, 3426761679103243, 3127058186392728},
+ {3187981953742084, 2855163365535635, 2396035850573347, 3426339364174055, 2041647909167010},
+ {463905214510220, 1910840871806134, 115888611524937, 1537009142155618, 880221457903699},
+ },
+ {
+ {5589672840238728, 3432294293459350, 5387677215955058, 6169144676112659, 5379715338757042},
+ {1784370156336156, 2235499907922716, 2025309612181078, 2188885065316605, 3233083367725482},
+ {417210119430620, 1641361429213146, 1508617462812435, 1831075688628217, 1813350286884393},
+ },
+ {
+ {3676762525127118, 5016274613231870, 5279594930346407, 2746860593795830, 4531082394479975},
+ {2603791557859206, 567981304762832, 3180006238725203, 2675077654404820, 258215834034235},
+ {1643563927005454, 1423516315292419, 46523883479803, 1501791298376850, 1157127033006661},
+ },
+ },
+ {
+ {
+ {4640633429716646, 4436352535262760, 5042663907988027, 4328339913162644, 4318409930240684},
+ {1650059244213924, 1415687339027798, 3751941600642035, 2204874486713656, 3546077689782506},
+ {1247200432261975, 265507035905438, 1620404126253617, 117362009527087, 1746435297969059},
+ },
+ {
+ {5340736267872142, 3295470429174750, 4407135163398927, 3488366482378904, 3746520348111790},
+ {1068629703061668, 3236562504536698, 3481748917474479, 2110232841828030, 1092532788851750},
+ {1306097687903586, 1372543655508231, 1658076721821581, 2200003583698537, 780636112677937},
+ },
+ {
+ {5226077937175337, 5692428823576533, 5689014150777050, 3908825240466348, 6345259720261058},
+ {3066336104509029, 2314860930152579, 3056640011863338, 2260092480216528, 2073254466378784},
+ {479894784370716, 1925880613677947, 2183487522494884, 625094381313712, 854845126872293},
+ },
+ {
+ {5197618157762598, 4433464121961190, 3260681654961795, 4120975634792281, 5835262176061498},
+ {817093479351430, 4088761935787052, 3171716785010059, 2728541872107727, 1520644895959802},
+ {1207982418891449, 1577854720087533, 2009037012572541, 1476807775109585, 764858983320152},
+ },
+ {
+ {4643752207568541, 4177425086748798, 2717351689863297, 4063904331524798, 6079476938692958},
+ {292623621294171, 1087309087737456, 2573455597713993, 859400146466928, 2565065720265056},
+ {1960514462005953, 1030291725190195, 357278058611993, 503261352420903, 409647200988996},
+ },
+ {
+ {4137436424426920, 3760583205467834, 5814704535202459, 3679343367155289, 3544651677301793},
+ {1640564024541742, 3450104780081118, 1372955845260037, 2487953912194947, 1964015174577549},
+ {1832104727099167, 996069167520846, 1100729754186688, 1771584084767106, 2117261745027080},
+ },
+ {
+ {4431020636065029, 5503695293870154, 4553592025467096, 4019460577334316, 4832018945114183},
+ {1199122074926019, 2522059134402784, 397875262207322, 3119865606750668, 1432109594857765},
+ {1875633950147766, 1109790076082089, 897660652998513, 1428078707156757, 908826481148722},
+ },
+ {
+ {5054013235620828, 5378852271051704, 4293253473160895, 4319499063151422, 5340758119594162},
+ {2634018106321626, 2505108247629684, 3126341578772617, 2016974307899050, 1468999769476078},
+ {2013224690617610, 881120726963113, 2087874148443678, 930634847072563, 2100154549645766},
+ },
+ {
+ {4096027168378681, 4674912073837464, 4651610619813038, 4659750027669693, 4079639323873143},
+ {651560684224625, 2530373654189494, 3125510882371828, 1936741789282769, 4026872663838631},
+ {1094258812694036, 1294242138409324, 1090035173467081, 1763568378228799, 1431407300427851},
+ },
+ {
+ {5901866474833548, 4953841416438018, 5227230958845012, 5669922347444024, 5683271169352586},
+ {2172262341405882, 2561868572136046, 3688730950551326, 2503867014426524, 2213093161812464},
+ {1951192547947024, 851119993124706, 1847432304733109, 1277897613708864, 601543383482271},
+ },
+ {
+ {3631710539670242, 3768950590313261, 5303952111138864, 5325131792733564, 5315344346171139},
+ {3338513542876810, 3006290156706597, 1350992246942434, 903865514364164, 3147437075515383},
+ {2230520732543357, 1272781658952307, 896500518331525, 1553870550296913, 1174834176365255},
+ },
+ {
+ {4212629881454302, 3511449460350501, 3310343538794185, 3281266357642722, 4487974828971768},
+ {2969785173831624, 1505727885325259, 2813024274382127, 1442092766966006, 2775912811267378},
+ {1226820412291019, 1429525834475644, 2118443840955994, 611048578379551, 1393279248359119},
+ },
+ {
+ {2549845597186375, 3623100753864553, 3499310120841001, 3967554171599715, 5734430215634972},
+ {1995271425552231, 3083791126213951, 3279752729240055, 1320836376731637, 2619696559790542},
+ {209938911194598, 1168941097549542, 1505719700014288, 296602403362327, 585510095036421},
+ },
+ {
+ {4596693410811983, 3239555606447835, 5319792910601399, 5807716310972140, 4978776737081211},
+ {4298118886570999, 2595714642338047, 2582204981507639, 2283950348816052, 2880808000087105},
+ {1625024000487589, 1577328585741835, 1748162688303583, 1508135442094103, 494130659185316},
+ },
+ {
+ {5133202328939711, 5161068400634691, 4982689133170151, 5479854286391464, 3974357722065660},
+ {2759508860286693, 3544879646603215, 2393702940511177, 1786833813469860, 2879003887330732},
+ {374825657994223, 798281160160783, 1037106323566812, 1491213365794340, 786385610113834},
+ },
+ },
+ }
+
+ GE_BASEPOINT_TABLE := &Gen_Multiply_Table_edwards25519_lo[0]
+}
diff --git a/core/crypto/_edwards25519/tools/edwards_gen_tables.odin b/core/crypto/_edwards25519/tools/edwards_gen_tables.odin
new file mode 100644
index 000000000..d05534d9d
--- /dev/null
+++ b/core/crypto/_edwards25519/tools/edwards_gen_tables.odin
@@ -0,0 +1,134 @@
+package weistrass_tools
+
+import ed "core:crypto/_edwards25519"
+import field "core:crypto/_fiat/field_curve25519"
+import scalar "core:crypto/_fiat/field_scalar25519"
+import "core:encoding/endian"
+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 ------
+*/`
+
+@(private, rodata)
+FE_D2 := field.Tight_Field_Element {
+ 1859910466990425,
+ 932731440258426,
+ 1072319116312658,
+ 1815898335770999,
+ 633789495995903,
+}
+
+main :: proc() {
+ Basepoint_Addend_Group_Element :: struct {
+ y2_minus_x2: field.Loose_Field_Element, // t1
+ y2_plus_x2: field.Loose_Field_Element, // t3
+ k_times_t2: field.Tight_Field_Element, // t4
+ }
+ Basepoint_Multiply_Table :: [15]Basepoint_Addend_Group_Element
+
+ ge_bp_addend_set := proc(ge_a: ^Basepoint_Addend_Group_Element, ge: ^ed.Group_Element) {
+ // We rescale so Z == 1, so T = X * Y
+ x_, y_, z_inv: field.Tight_Field_Element
+ field.fe_carry_inv(&z_inv, field.fe_relax_cast(&ge.z))
+ field.fe_carry_mul(&x_, field.fe_relax_cast(&ge.x), field.fe_relax_cast(&z_inv))
+ field.fe_carry_mul(&y_, field.fe_relax_cast(&ge.y), field.fe_relax_cast(&z_inv))
+
+ field.fe_sub(&ge_a.y2_minus_x2, &y_, &x_)
+ field.fe_add(&ge_a.y2_plus_x2, &y_, &x_)
+ field.fe_carry_mul(&ge_a.k_times_t2, field.fe_relax_cast(&x_), field.fe_relax_cast(&y_))
+ field.fe_carry_mul(&ge_a.k_times_t2, field.fe_relax_cast(&ge_a.k_times_t2), field.fe_relax_cast(&FE_D2))
+ }
+
+ Multiply_Table_hi: [32]Basepoint_Multiply_Table
+ Multiply_Table_lo: [32]Basepoint_Multiply_Table
+
+ sc_set_unchecked := proc(sc: ^scalar.Non_Montgomery_Domain_Field_Element, b: []byte) {
+ sc[0] = endian.unchecked_get_u64le(b[0:])
+ sc[1] = endian.unchecked_get_u64le(b[8:])
+ sc[2] = endian.unchecked_get_u64le(b[16:])
+ sc[3] = endian.unchecked_get_u64le(b[24:])
+ }
+
+ g, p: ed.Group_Element
+ ed.ge_generator(&g)
+
+ sc: scalar.Non_Montgomery_Domain_Field_Element
+
+ // Precompute ([1,15] << n) * G multiples of G, LSB->MSB
+ for i in 0..<32 {
+ b: [32]byte
+ for j in 1..<16 {
+ b[i] = u8(j)
+ sc_set_unchecked(&sc, b[:])
+ ed.ge_scalarmult_raw(&p, &g, &sc, true)
+ ge_bp_addend_set(&Multiply_Table_lo[i][j-1], &p)
+
+ b[i] = u8(j) << 4
+ sc_set_unchecked(&sc, b[:])
+ ed.ge_scalarmult_raw(&p, &g, &sc, true)
+ ge_bp_addend_set(&Multiply_Table_hi[i][j-1], &p)
+
+ b[i] = 0
+ }
+ }
+
+ fn := path.join({ODIN_ROOT, "core", "crypto", "_edwards25519", "edwards25519_table.odin"})
+ bld: strings.Builder
+ w := strings.to_writer(&bld)
+
+ fmt.wprintln(w, "package _edwards25519")
+ 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.wprintln(w, "\tGen_Multiply_Table_edwards25519_lo := [32]Basepoint_Multiply_Table {")
+ for &v in Multiply_Table_lo {
+ fmt.wprintln(w, "\t\t{")
+ for &ap in v {
+ fmt.wprintln(w, "\t\t\t{")
+
+ t1, t3, t4 := &ap.y2_minus_x2, &ap.y2_plus_x2, &ap.k_times_t2
+ fmt.wprintf(w, "\t\t\t\t{{%d, %d, %d, %d, %d},\n", t1[0], t1[1], t1[2], t1[3], t1[4])
+ fmt.wprintf(w, "\t\t\t\t{{%d, %d, %d, %d, %d},\n", t3[0], t3[1], t3[2], t3[3], t3[4])
+ fmt.wprintf(w, "\t\t\t\t{{%d, %d, %d, %d, %d},\n", t4[0], t4[1], t4[2], t4[3], t4[4])
+
+ fmt.wprintln(w, "\t\t\t},")
+ }
+ fmt.wprintln(w, "\t\t},")
+ }
+ fmt.wprintln(w, "\t}\n")
+
+ fmt.wprintln(w, "\t@(private,rodata)")
+ fmt.wprintln(w, "\tGen_Multiply_Table_edwards25519_hi := [32]Basepoint_Multiply_Table {")
+ for &v in Multiply_Table_hi {
+ fmt.wprintln(w, "\t\t{")
+ for &ap in v {
+ fmt.wprintln(w, "\t\t\t{")
+
+ t1, t3, t4 := &ap.y2_minus_x2, &ap.y2_plus_x2, &ap.k_times_t2
+ fmt.wprintf(w, "\t\t\t\t{{%d, %d, %d, %d, %d},\n", t1[0], t1[1], t1[2], t1[3], t1[4])
+ fmt.wprintf(w, "\t\t\t\t{{%d, %d, %d, %d, %d},\n", t3[0], t3[1], t3[2], t3[3], t3[4])
+ fmt.wprintf(w, "\t\t\t\t{{%d, %d, %d, %d, %d},\n", t4[0], t4[1], t4[2], t4[3], t4[4])
+
+ fmt.wprintln(w, "\t\t\t},")
+ }
+ fmt.wprintln(w, "\t\t},")
+ }
+ fmt.wprintln(w, "\t}\n")
+
+ fmt.wprintln(w, "\tGE_BASEPOINT_TABLE := &Gen_Multiply_Table_edwards25519_lo[0]")
+
+ fmt.wprintln(w, "}")
+
+ _ = os.write_entire_file(fn, transmute([]byte)(strings.to_string(bld)))
+}
diff --git a/core/crypto/_fiat/field_p256r1/field.odin b/core/crypto/_fiat/field_p256r1/field.odin
new file mode 100644
index 000000000..b1662fd48
--- /dev/null
+++ b/core/crypto/_fiat/field_p256r1/field.odin
@@ -0,0 +1,346 @@
+package field_p256r1
+
+import subtle "core:crypto/_subtle"
+import "core:encoding/endian"
+import "core:math/bits"
+import "core:mem"
+
+fe_clear :: proc "contextless" (arg1: ^Montgomery_Domain_Field_Element) {
+ mem.zero_explicit(arg1, size_of(Montgomery_Domain_Field_Element))
+}
+
+fe_clear_vec :: proc "contextless" (
+ arg1: []^Montgomery_Domain_Field_Element,
+) {
+ for fe in arg1 {
+ fe_clear(fe)
+ }
+}
+
+fe_from_bytes :: proc "contextless" (
+ out1: ^Montgomery_Domain_Field_Element,
+ arg1: []byte,
+ unsafe_assume_canonical := false,
+) -> bool {
+ ensure_contextless(len(arg1) == 32, "p256r1: invalid fe input buffer")
+
+ // Note: We assume the input is in big-endian.
+ tmp := Non_Montgomery_Domain_Field_Element {
+ endian.unchecked_get_u64be(arg1[24:]),
+ endian.unchecked_get_u64be(arg1[16:]),
+ endian.unchecked_get_u64be(arg1[8:]),
+ endian.unchecked_get_u64be(arg1[0:]),
+ }
+ defer mem.zero_explicit(&tmp, size_of(tmp))
+
+ // Check that tmp is in the the range [0, ELL).
+ if !unsafe_assume_canonical {
+ _, borrow := bits.sub_u64(ELL[0] - 1, tmp[0], 0)
+ _, borrow = bits.sub_u64(ELL[1], tmp[1], borrow)
+ _, borrow = bits.sub_u64(ELL[2], tmp[2], borrow)
+ _, borrow = bits.sub_u64(ELL[3], tmp[3], borrow)
+ if borrow != 0 {
+ return false
+ }
+ }
+
+ fe_to_montgomery(out1, &tmp)
+
+ return true
+}
+
+fe_to_bytes :: proc "contextless" (out1: []byte, arg1: ^Montgomery_Domain_Field_Element) {
+ ensure_contextless(len(out1) == 32, "p256r1: invalid fe output buffer")
+
+ tmp: Non_Montgomery_Domain_Field_Element
+ fe_from_montgomery(&tmp, arg1)
+
+ // Note: Likewise, output in big-endian.
+ endian.unchecked_put_u64be(out1[24:], tmp[0])
+ endian.unchecked_put_u64be(out1[16:], tmp[1])
+ endian.unchecked_put_u64be(out1[8:], tmp[2])
+ endian.unchecked_put_u64be(out1[0:], tmp[3])
+
+ mem.zero_explicit(&tmp, size_of(tmp))
+}
+
+@(require_results)
+fe_equal :: proc "contextless" (arg1, arg2: ^Montgomery_Domain_Field_Element) -> int {
+ tmp: Montgomery_Domain_Field_Element
+ fe_sub(&tmp, arg1, arg2)
+
+ // This will only underflow iff arg1 == arg2, and we return the borrow,
+ // which will be 1.
+ is_eq := subtle.u64_is_zero(fe_non_zero(&tmp))
+
+ fe_clear(&tmp)
+
+ return int(is_eq)
+}
+
+@(require_results)
+fe_is_odd :: proc "contextless" (arg1: ^Montgomery_Domain_Field_Element) -> int {
+ tmp: Non_Montgomery_Domain_Field_Element
+ defer mem.zero_explicit(&tmp, size_of(tmp))
+
+ fe_from_montgomery(&tmp, arg1)
+ return int(tmp[0] & 1)
+}
+
+fe_pow2k :: proc "contextless" (
+ out1: ^Montgomery_Domain_Field_Element,
+ arg1: ^Montgomery_Domain_Field_Element,
+ arg2: uint,
+) {
+ // Special case: `arg1^(2 * 0) = 1`, though this should never happen.
+ if arg2 == 0 {
+ fe_one(out1)
+ return
+ }
+
+ fe_square(out1, arg1)
+ for _ in 1 ..< arg2 {
+ fe_square(out1, out1)
+ }
+}
+
+fe_inv :: proc "contextless" (out1, arg1: ^Montgomery_Domain_Field_Element) {
+ // Inversion computation is derived from the addition chain:
+ //
+ // _10 = 2*1
+ // _11 = 1 + _10
+ // _110 = 2*_11
+ // _111 = 1 + _110
+ // _111000 = _111 << 3
+ // _111111 = _111 + _111000
+ // x12 = _111111 << 6 + _111111
+ // x15 = x12 << 3 + _111
+ // x16 = 2*x15 + 1
+ // x32 = x16 << 16 + x16
+ // i53 = x32 << 15
+ // x47 = x15 + i53
+ // i263 = ((i53 << 17 + 1) << 143 + x47) << 47
+ // return (x47 + i263) << 2
+ //
+ // Operations: 255 squares 11 multiplies
+ //
+ // Generated by github.com/mmcloughlin/addchain v0.4.0.
+
+ // Note: Need to stash `arg1` (`xx`) in the case that `out1`/`arg1` alias,
+ // as `arg1` is used after `out1` has been altered.
+ t0, t1, xx: Montgomery_Domain_Field_Element = ---, ---, arg1^
+
+ // Step 1: z = x^0x2
+ fe_square(out1, arg1)
+
+ // Step 2: z = x^0x3
+ fe_mul(out1, &xx, out1)
+
+ // Step 3: z = x^0x6
+ fe_square(out1, out1)
+
+ // Step 4: z = x^0x7
+ fe_mul(out1, &xx, out1)
+
+ // Step 7: t0 = x^0x38
+ fe_pow2k(&t0, out1, 3)
+
+ // Step 8: t0 = x^0x3f
+ fe_mul(&t0, out1, &t0)
+
+ // Step 14: t1 = x^0xfc0
+ fe_pow2k(&t1, &t0, 6)
+
+ // Step 15: t0 = x^0xfff
+ fe_mul(&t0, &t0, &t1)
+
+ // Step 18: t0 = x^0x7ff8
+ fe_pow2k(&t0, &t0, 3)
+
+ // Step 19: z = x^0x7fff
+ fe_mul(out1, out1, &t0)
+
+ // Step 20: t0 = x^0xfffe
+ fe_square(&t0, out1)
+
+ // Step 21: t0 = x^0xffff
+ fe_mul(&t0, &xx, &t0)
+
+ // Step 37: t1 = x^0xffff0000
+ fe_pow2k(&t1, &t0, 16)
+
+ // Step 38: t0 = x^0xffffffff
+ fe_mul(&t0, &t0, &t1)
+
+ // Step 53: t0 = x^0x7fffffff8000
+ fe_pow2k(&t0, &t0, 15)
+
+ // Step 54: z = x^0x7fffffffffff
+ fe_mul(out1, out1, &t0)
+
+ // Step 71: t0 = x^0xffffffff00000000
+ fe_pow2k(&t0, &t0, 17)
+
+ // Step 72: t0 = x^0xffffffff00000001
+ fe_mul(&t0, &xx, &t0)
+
+ // Step 215: t0 = x^0x7fffffff80000000800000000000000000000000000000000000
+ fe_pow2k(&t0, &t0, 143)
+
+ // Step 216: t0 = x^0x7fffffff800000008000000000000000000000007fffffffffff
+ fe_mul(&t0, out1, &t0)
+
+ // Step 263: t0 = x^0x3fffffffc00000004000000000000000000000003fffffffffff800000000000
+ fe_pow2k(&t0, &t0, 47)
+
+ // Step 264: z = x^0x3fffffffc00000004000000000000000000000003fffffffffffffffffffffff
+ fe_mul(out1, out1, &t0)
+
+ // Step 266: z = x^0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc
+ fe_pow2k(out1, out1, 2)
+
+ fe_mul(out1, out1, &xx)
+
+ fe_clear_vec([]^Montgomery_Domain_Field_Element{&t0, &t1, &xx})
+}
+
+@(require_results)
+fe_sqrt :: proc "contextless" (out1, arg1: ^Montgomery_Domain_Field_Element) -> int {
+ // Square root candidate can be derived via exponentiation by `(p + 1) / 4`
+ // From sage: 28948022302589062190674361737351893382521535853822578548883407827216774463488
+ //
+ // // Inversion computation is derived from the addition chain:
+ //
+ // _10 = 2*1
+ // _11 = 1 + _10
+ // _1100 = _11 << 2
+ // _1111 = _11 + _1100
+ // _11110000 = _1111 << 4
+ // _11111111 = _1111 + _11110000
+ // x16 = _11111111 << 8 + _11111111
+ // x32 = x16 << 16 + x16
+ // return ((x32 << 32 + 1) << 96 + 1) << 94
+ //
+ // Operations: 253 squares 7 multiplies
+ //
+ // Generated by github.com/mmcloughlin/addchain v0.4.0.
+
+ // Likewise this tramples over arg1, so stash another copy.
+ t0, xx: Montgomery_Domain_Field_Element = ---, arg1^
+
+ // Step 1: z = x^0x2
+ fe_square(out1, arg1)
+
+ // Step 2: z = x^0x3
+ fe_mul(out1, &xx, out1)
+
+ // Step 4: t0 = x^0xc
+ fe_pow2k(&t0, &xx, 2)
+
+ // Step 5: z = x^0xf
+ fe_mul(out1, out1, &t0)
+
+ // Step 9: t0 = x^0xf0
+ fe_pow2k(&t0, out1, 4)
+
+ // Step 10: z = x^0xff
+ fe_mul(out1, out1, &t0)
+
+ // Step 18: t0 = x^0xff00
+ fe_pow2k(&t0, out1, 8)
+
+ // Step 19: z = x^0xffff
+ fe_mul(out1, out1, &t0)
+
+ // Step 35: t0 = x^0xffff0000
+ fe_pow2k(&t0, out1, 16)
+
+ // Step 36: z = x^0xffffffff
+ fe_mul(out1, out1, &t0)
+
+ // Step 68: z = x^0xffffffff00000000
+ fe_pow2k(out1, out1, 32)
+
+ // Step 69: z = x^0xffffffff00000001
+ fe_mul(out1, &xx, out1)
+
+ // Step 165: z = x^0xffffffff00000001000000000000000000000000
+ fe_pow2k(out1, out1, 96)
+
+ // Step 166: z = x^0xffffffff00000001000000000000000000000001
+ fe_mul(out1, &xx, out1)
+
+ // Step 260: z = x^0x3fffffffc0000000400000000000000000000000400000000000000000000000
+ fe_pow2k(out1, out1, 94)
+
+ // Ensure that our candidate is actually the square root.
+ check, zero: Montgomery_Domain_Field_Element
+ fe_square(&check, out1)
+
+ is_valid := fe_equal(&check, &xx)
+ fe_cond_select(out1, &zero, out1, is_valid)
+
+ fe_clear_vec([]^Montgomery_Domain_Field_Element{&t0, &xx, &check})
+
+ return is_valid
+
+}
+
+fe_zero :: proc "contextless" (out1: ^Montgomery_Domain_Field_Element) {
+ out1[0] = 0
+ out1[1] = 0
+ out1[2] = 0
+ out1[3] = 0
+}
+
+fe_set :: proc "contextless" (out1, arg1: ^Montgomery_Domain_Field_Element) {
+ x1 := arg1[0]
+ x2 := arg1[1]
+ x3 := arg1[2]
+ x4 := arg1[3]
+ out1[0] = x1
+ out1[1] = x2
+ out1[2] = x3
+ out1[3] = x4
+}
+
+@(optimization_mode = "none")
+fe_cond_swap :: #force_no_inline proc "contextless" (out1, out2: ^Montgomery_Domain_Field_Element, arg1: int) {
+ mask := (u64(arg1) * 0xffffffffffffffff)
+ x := (out1[0] ~ out2[0]) & mask
+ x1, y1 := out1[0] ~ x, out2[0] ~ x
+ x = (out1[1] ~ out2[1]) & mask
+ x2, y2 := out1[1] ~ x, out2[1] ~ x
+ x = (out1[2] ~ out2[2]) & mask
+ x3, y3 := out1[2] ~ x, out2[2] ~ x
+ x = (out1[3] ~ out2[3]) & mask
+ x4, y4 := out1[3] ~ x, out2[3] ~ x
+ out1[0], out2[0] = x1, y1
+ out1[1], out2[1] = x2, y2
+ out1[2], out2[2] = x3, y3
+ out1[3], out2[3] = x4, y4
+}
+
+@(optimization_mode = "none")
+fe_cond_select :: #force_no_inline proc "contextless" (
+ out1, arg1, arg2: ^Montgomery_Domain_Field_Element,
+ arg3: int,
+) {
+ mask := (u64(arg3) * 0xffffffffffffffff)
+ x1 := ((mask & arg2[0]) | ((~mask) & arg1[0]))
+ x2 := ((mask & arg2[1]) | ((~mask) & arg1[1]))
+ x3 := ((mask & arg2[2]) | ((~mask) & arg1[2]))
+ x4 := ((mask & arg2[3]) | ((~mask) & arg1[3]))
+ out1[0] = x1
+ out1[1] = x2
+ out1[2] = x3
+ out1[3] = x4
+}
+
+fe_cond_negate :: proc "contextless" (out1, arg1: ^Montgomery_Domain_Field_Element, ctrl: int) {
+ tmp1: Montgomery_Domain_Field_Element = ---
+ fe_opp(&tmp1, arg1)
+ fe_cond_select(out1, arg1, &tmp1, ctrl)
+
+ fe_clear(&tmp1)
+}
diff --git a/core/crypto/_fiat/field_p256r1/field64.odin b/core/crypto/_fiat/field_p256r1/field64.odin
new file mode 100644
index 000000000..940f2cd07
--- /dev/null
+++ b/core/crypto/_fiat/field_p256r1/field64.odin
@@ -0,0 +1,501 @@
+// The BSD 1-Clause License (BSD-1-Clause)
+//
+// Copyright (c) 2015-2020 the fiat-crypto authors (see the AUTHORS file)
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// THIS SOFTWARE IS PROVIDED BY the fiat-crypto authors "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design,
+// Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package field_p256r1
+
+// The file provides arithmetic on the field Z/(2^256 - 2^224 + 2^192 + 2^96 - 1)
+// using a 64-bit Montgomery form internal representation. It is derived
+// primarily from the machine generated Golang output from the fiat-crypto
+// project.
+//
+// While the base implementation is provably correct, this implementation
+// makes no such claims as the port and optimizations were done by hand.
+//
+// WARNING: While big-endian is the common representation used for this
+// curve, the fiat output uses least-significant-limb first.
+
+import fiat "core:crypto/_fiat"
+import "core:math/bits"
+
+// ELL is the saturated representation of the field order, least-significant
+// limb first.
+ELL :: [4]u64{0xffffffffffffffff, 0xffffffff, 0x0, 0xffffffff00000001}
+
+Montgomery_Domain_Field_Element :: distinct [4]u64
+Non_Montgomery_Domain_Field_Element :: distinct [4]u64
+
+fe_mul :: proc "contextless" (out1, arg1, arg2: ^Montgomery_Domain_Field_Element) {
+ x1 := arg1[1]
+ x2 := arg1[2]
+ x3 := arg1[3]
+ x4 := arg1[0]
+ x6, x5 := bits.mul_u64(x4, arg2[3])
+ x8, x7 := bits.mul_u64(x4, arg2[2])
+ x10, x9 := bits.mul_u64(x4, arg2[1])
+ x12, x11 := bits.mul_u64(x4, arg2[0])
+ x13, x14 := bits.add_u64(x12, x9, u64(0x0))
+ x15, x16 := bits.add_u64(x10, x7, u64(fiat.u1(x14)))
+ x17, x18 := bits.add_u64(x8, x5, u64(fiat.u1(x16)))
+ x19 := (u64(fiat.u1(x18)) + x6)
+ x21, x20 := bits.mul_u64(x11, 0xffffffff00000001)
+ x23, x22 := bits.mul_u64(x11, 0xffffffff)
+ x25, x24 := bits.mul_u64(x11, 0xffffffffffffffff)
+ x26, x27 := bits.add_u64(x25, x22, u64(0x0))
+ x28 := (u64(fiat.u1(x27)) + x23)
+ _, x30 := bits.add_u64(x11, x24, u64(0x0))
+ x31, x32 := bits.add_u64(x13, x26, u64(fiat.u1(x30)))
+ x33, x34 := bits.add_u64(x15, x28, u64(fiat.u1(x32)))
+ x35, x36 := bits.add_u64(x17, x20, u64(fiat.u1(x34)))
+ x37, x38 := bits.add_u64(x19, x21, u64(fiat.u1(x36)))
+ x40, x39 := bits.mul_u64(x1, arg2[3])
+ x42, x41 := bits.mul_u64(x1, arg2[2])
+ x44, x43 := bits.mul_u64(x1, arg2[1])
+ x46, x45 := bits.mul_u64(x1, arg2[0])
+ x47, x48 := bits.add_u64(x46, x43, u64(0x0))
+ x49, x50 := bits.add_u64(x44, x41, u64(fiat.u1(x48)))
+ x51, x52 := bits.add_u64(x42, x39, u64(fiat.u1(x50)))
+ x53 := (u64(fiat.u1(x52)) + x40)
+ x54, x55 := bits.add_u64(x31, x45, u64(0x0))
+ x56, x57 := bits.add_u64(x33, x47, u64(fiat.u1(x55)))
+ x58, x59 := bits.add_u64(x35, x49, u64(fiat.u1(x57)))
+ x60, x61 := bits.add_u64(x37, x51, u64(fiat.u1(x59)))
+ x62, x63 := bits.add_u64(u64(fiat.u1(x38)), x53, u64(fiat.u1(x61)))
+ x65, x64 := bits.mul_u64(x54, 0xffffffff00000001)
+ x67, x66 := bits.mul_u64(x54, 0xffffffff)
+ x69, x68 := bits.mul_u64(x54, 0xffffffffffffffff)
+ x70, x71 := bits.add_u64(x69, x66, u64(0x0))
+ x72 := (u64(fiat.u1(x71)) + x67)
+ _, x74 := bits.add_u64(x54, x68, u64(0x0))
+ x75, x76 := bits.add_u64(x56, x70, u64(fiat.u1(x74)))
+ x77, x78 := bits.add_u64(x58, x72, u64(fiat.u1(x76)))
+ x79, x80 := bits.add_u64(x60, x64, u64(fiat.u1(x78)))
+ x81, x82 := bits.add_u64(x62, x65, u64(fiat.u1(x80)))
+ x83 := (u64(fiat.u1(x82)) + u64(fiat.u1(x63)))
+ x85, x84 := bits.mul_u64(x2, arg2[3])
+ x87, x86 := bits.mul_u64(x2, arg2[2])
+ x89, x88 := bits.mul_u64(x2, arg2[1])
+ x91, x90 := bits.mul_u64(x2, arg2[0])
+ x92, x93 := bits.add_u64(x91, x88, u64(0x0))
+ x94, x95 := bits.add_u64(x89, x86, u64(fiat.u1(x93)))
+ x96, x97 := bits.add_u64(x87, x84, u64(fiat.u1(x95)))
+ x98 := (u64(fiat.u1(x97)) + x85)
+ x99, x100 := bits.add_u64(x75, x90, u64(0x0))
+ x101, x102 := bits.add_u64(x77, x92, u64(fiat.u1(x100)))
+ x103, x104 := bits.add_u64(x79, x94, u64(fiat.u1(x102)))
+ x105, x106 := bits.add_u64(x81, x96, u64(fiat.u1(x104)))
+ x107, x108 := bits.add_u64(x83, x98, u64(fiat.u1(x106)))
+ x110, x109 := bits.mul_u64(x99, 0xffffffff00000001)
+ x112, x111 := bits.mul_u64(x99, 0xffffffff)
+ x114, x113 := bits.mul_u64(x99, 0xffffffffffffffff)
+ x115, x116 := bits.add_u64(x114, x111, u64(0x0))
+ x117 := (u64(fiat.u1(x116)) + x112)
+ _, x119 := bits.add_u64(x99, x113, u64(0x0))
+ x120, x121 := bits.add_u64(x101, x115, u64(fiat.u1(x119)))
+ x122, x123 := bits.add_u64(x103, x117, u64(fiat.u1(x121)))
+ x124, x125 := bits.add_u64(x105, x109, u64(fiat.u1(x123)))
+ x126, x127 := bits.add_u64(x107, x110, u64(fiat.u1(x125)))
+ x128 := (u64(fiat.u1(x127)) + u64(fiat.u1(x108)))
+ x130, x129 := bits.mul_u64(x3, arg2[3])
+ x132, x131 := bits.mul_u64(x3, arg2[2])
+ x134, x133 := bits.mul_u64(x3, arg2[1])
+ x136, x135 := bits.mul_u64(x3, arg2[0])
+ x137, x138 := bits.add_u64(x136, x133, u64(0x0))
+ x139, x140 := bits.add_u64(x134, x131, u64(fiat.u1(x138)))
+ x141, x142 := bits.add_u64(x132, x129, u64(fiat.u1(x140)))
+ x143 := (u64(fiat.u1(x142)) + x130)
+ x144, x145 := bits.add_u64(x120, x135, u64(0x0))
+ x146, x147 := bits.add_u64(x122, x137, u64(fiat.u1(x145)))
+ x148, x149 := bits.add_u64(x124, x139, u64(fiat.u1(x147)))
+ x150, x151 := bits.add_u64(x126, x141, u64(fiat.u1(x149)))
+ x152, x153 := bits.add_u64(x128, x143, u64(fiat.u1(x151)))
+ x155, x154 := bits.mul_u64(x144, 0xffffffff00000001)
+ x157, x156 := bits.mul_u64(x144, 0xffffffff)
+ x159, x158 := bits.mul_u64(x144, 0xffffffffffffffff)
+ x160, x161 := bits.add_u64(x159, x156, u64(0x0))
+ x162 := (u64(fiat.u1(x161)) + x157)
+ _, x164 := bits.add_u64(x144, x158, u64(0x0))
+ x165, x166 := bits.add_u64(x146, x160, u64(fiat.u1(x164)))
+ x167, x168 := bits.add_u64(x148, x162, u64(fiat.u1(x166)))
+ x169, x170 := bits.add_u64(x150, x154, u64(fiat.u1(x168)))
+ x171, x172 := bits.add_u64(x152, x155, u64(fiat.u1(x170)))
+ x173 := (u64(fiat.u1(x172)) + u64(fiat.u1(x153)))
+ x174, x175 := bits.sub_u64(x165, 0xffffffffffffffff, u64(0x0))
+ x176, x177 := bits.sub_u64(x167, 0xffffffff, u64(fiat.u1(x175)))
+ x178, x179 := bits.sub_u64(x169, u64(0x0), u64(fiat.u1(x177)))
+ x180, x181 := bits.sub_u64(x171, 0xffffffff00000001, u64(fiat.u1(x179)))
+ _, x183 := bits.sub_u64(x173, u64(0x0), u64(fiat.u1(x181)))
+ x184 := fiat.cmovznz_u64(fiat.u1(x183), x174, x165)
+ x185 := fiat.cmovznz_u64(fiat.u1(x183), x176, x167)
+ x186 := fiat.cmovznz_u64(fiat.u1(x183), x178, x169)
+ x187 := fiat.cmovznz_u64(fiat.u1(x183), x180, x171)
+ out1[0] = x184
+ out1[1] = x185
+ out1[2] = x186
+ out1[3] = x187
+}
+
+fe_square :: proc "contextless" (out1, arg1: ^Montgomery_Domain_Field_Element) {
+ x1 := arg1[1]
+ x2 := arg1[2]
+ x3 := arg1[3]
+ x4 := arg1[0]
+ x6, x5 := bits.mul_u64(x4, arg1[3])
+ x8, x7 := bits.mul_u64(x4, arg1[2])
+ x10, x9 := bits.mul_u64(x4, arg1[1])
+ x12, x11 := bits.mul_u64(x4, arg1[0])
+ x13, x14 := bits.add_u64(x12, x9, u64(0x0))
+ x15, x16 := bits.add_u64(x10, x7, u64(fiat.u1(x14)))
+ x17, x18 := bits.add_u64(x8, x5, u64(fiat.u1(x16)))
+ x19 := (u64(fiat.u1(x18)) + x6)
+ x21, x20 := bits.mul_u64(x11, 0xffffffff00000001)
+ x23, x22 := bits.mul_u64(x11, 0xffffffff)
+ x25, x24 := bits.mul_u64(x11, 0xffffffffffffffff)
+ x26, x27 := bits.add_u64(x25, x22, u64(0x0))
+ x28 := (u64(fiat.u1(x27)) + x23)
+ _, x30 := bits.add_u64(x11, x24, u64(0x0))
+ x31, x32 := bits.add_u64(x13, x26, u64(fiat.u1(x30)))
+ x33, x34 := bits.add_u64(x15, x28, u64(fiat.u1(x32)))
+ x35, x36 := bits.add_u64(x17, x20, u64(fiat.u1(x34)))
+ x37, x38 := bits.add_u64(x19, x21, u64(fiat.u1(x36)))
+ x40, x39 := bits.mul_u64(x1, arg1[3])
+ x42, x41 := bits.mul_u64(x1, arg1[2])
+ x44, x43 := bits.mul_u64(x1, arg1[1])
+ x46, x45 := bits.mul_u64(x1, arg1[0])
+ x47, x48 := bits.add_u64(x46, x43, u64(0x0))
+ x49, x50 := bits.add_u64(x44, x41, u64(fiat.u1(x48)))
+ x51, x52 := bits.add_u64(x42, x39, u64(fiat.u1(x50)))
+ x53 := (u64(fiat.u1(x52)) + x40)
+ x54, x55 := bits.add_u64(x31, x45, u64(0x0))
+ x56, x57 := bits.add_u64(x33, x47, u64(fiat.u1(x55)))
+ x58, x59 := bits.add_u64(x35, x49, u64(fiat.u1(x57)))
+ x60, x61 := bits.add_u64(x37, x51, u64(fiat.u1(x59)))
+ x62, x63 := bits.add_u64(u64(fiat.u1(x38)), x53, u64(fiat.u1(x61)))
+ x65, x64 := bits.mul_u64(x54, 0xffffffff00000001)
+ x67, x66 := bits.mul_u64(x54, 0xffffffff)
+ x69, x68 := bits.mul_u64(x54, 0xffffffffffffffff)
+ x70, x71 := bits.add_u64(x69, x66, u64(0x0))
+ x72 := (u64(fiat.u1(x71)) + x67)
+ _, x74 := bits.add_u64(x54, x68, u64(0x0))
+ x75, x76 := bits.add_u64(x56, x70, u64(fiat.u1(x74)))
+ x77, x78 := bits.add_u64(x58, x72, u64(fiat.u1(x76)))
+ x79, x80 := bits.add_u64(x60, x64, u64(fiat.u1(x78)))
+ x81, x82 := bits.add_u64(x62, x65, u64(fiat.u1(x80)))
+ x83 := (u64(fiat.u1(x82)) + u64(fiat.u1(x63)))
+ x85, x84 := bits.mul_u64(x2, arg1[3])
+ x87, x86 := bits.mul_u64(x2, arg1[2])
+ x89, x88 := bits.mul_u64(x2, arg1[1])
+ x91, x90 := bits.mul_u64(x2, arg1[0])
+ x92, x93 := bits.add_u64(x91, x88, u64(0x0))
+ x94, x95 := bits.add_u64(x89, x86, u64(fiat.u1(x93)))
+ x96, x97 := bits.add_u64(x87, x84, u64(fiat.u1(x95)))
+ x98 := (u64(fiat.u1(x97)) + x85)
+ x99, x100 := bits.add_u64(x75, x90, u64(0x0))
+ x101, x102 := bits.add_u64(x77, x92, u64(fiat.u1(x100)))
+ x103, x104 := bits.add_u64(x79, x94, u64(fiat.u1(x102)))
+ x105, x106 := bits.add_u64(x81, x96, u64(fiat.u1(x104)))
+ x107, x108 := bits.add_u64(x83, x98, u64(fiat.u1(x106)))
+ x110, x109 := bits.mul_u64(x99, 0xffffffff00000001)
+ x112, x111 := bits.mul_u64(x99, 0xffffffff)
+ x114, x113 := bits.mul_u64(x99, 0xffffffffffffffff)
+ x115, x116 := bits.add_u64(x114, x111, u64(0x0))
+ x117 := (u64(fiat.u1(x116)) + x112)
+ _, x119 := bits.add_u64(x99, x113, u64(0x0))
+ x120, x121 := bits.add_u64(x101, x115, u64(fiat.u1(x119)))
+ x122, x123 := bits.add_u64(x103, x117, u64(fiat.u1(x121)))
+ x124, x125 := bits.add_u64(x105, x109, u64(fiat.u1(x123)))
+ x126, x127 := bits.add_u64(x107, x110, u64(fiat.u1(x125)))
+ x128 := (u64(fiat.u1(x127)) + u64(fiat.u1(x108)))
+ x130, x129 := bits.mul_u64(x3, arg1[3])
+ x132, x131 := bits.mul_u64(x3, arg1[2])
+ x134, x133 := bits.mul_u64(x3, arg1[1])
+ x136, x135 := bits.mul_u64(x3, arg1[0])
+ x137, x138 := bits.add_u64(x136, x133, u64(0x0))
+ x139, x140 := bits.add_u64(x134, x131, u64(fiat.u1(x138)))
+ x141, x142 := bits.add_u64(x132, x129, u64(fiat.u1(x140)))
+ x143 := (u64(fiat.u1(x142)) + x130)
+ x144, x145 := bits.add_u64(x120, x135, u64(0x0))
+ x146, x147 := bits.add_u64(x122, x137, u64(fiat.u1(x145)))
+ x148, x149 := bits.add_u64(x124, x139, u64(fiat.u1(x147)))
+ x150, x151 := bits.add_u64(x126, x141, u64(fiat.u1(x149)))
+ x152, x153 := bits.add_u64(x128, x143, u64(fiat.u1(x151)))
+ x155, x154 := bits.mul_u64(x144, 0xffffffff00000001)
+ x157, x156 := bits.mul_u64(x144, 0xffffffff)
+ x159, x158 := bits.mul_u64(x144, 0xffffffffffffffff)
+ x160, x161 := bits.add_u64(x159, x156, u64(0x0))
+ x162 := (u64(fiat.u1(x161)) + x157)
+ _, x164 := bits.add_u64(x144, x158, u64(0x0))
+ x165, x166 := bits.add_u64(x146, x160, u64(fiat.u1(x164)))
+ x167, x168 := bits.add_u64(x148, x162, u64(fiat.u1(x166)))
+ x169, x170 := bits.add_u64(x150, x154, u64(fiat.u1(x168)))
+ x171, x172 := bits.add_u64(x152, x155, u64(fiat.u1(x170)))
+ x173 := (u64(fiat.u1(x172)) + u64(fiat.u1(x153)))
+ x174, x175 := bits.sub_u64(x165, 0xffffffffffffffff, u64(0x0))
+ x176, x177 := bits.sub_u64(x167, 0xffffffff, u64(fiat.u1(x175)))
+ x178, x179 := bits.sub_u64(x169, u64(0x0), u64(fiat.u1(x177)))
+ x180, x181 := bits.sub_u64(x171, 0xffffffff00000001, u64(fiat.u1(x179)))
+ _, x183 := bits.sub_u64(x173, u64(0x0), u64(fiat.u1(x181)))
+ x184 := fiat.cmovznz_u64(fiat.u1(x183), x174, x165)
+ x185 := fiat.cmovznz_u64(fiat.u1(x183), x176, x167)
+ x186 := fiat.cmovznz_u64(fiat.u1(x183), x178, x169)
+ x187 := fiat.cmovznz_u64(fiat.u1(x183), x180, x171)
+ out1[0] = x184
+ out1[1] = x185
+ out1[2] = x186
+ out1[3] = x187
+}
+
+fe_add :: proc "contextless" (out1, arg1, arg2: ^Montgomery_Domain_Field_Element) {
+ x1, x2 := bits.add_u64(arg1[0], arg2[0], u64(0x0))
+ x3, x4 := bits.add_u64(arg1[1], arg2[1], u64(fiat.u1(x2)))
+ x5, x6 := bits.add_u64(arg1[2], arg2[2], u64(fiat.u1(x4)))
+ x7, x8 := bits.add_u64(arg1[3], arg2[3], u64(fiat.u1(x6)))
+ x9, x10 := bits.sub_u64(x1, 0xffffffffffffffff, u64(0x0))
+ x11, x12 := bits.sub_u64(x3, 0xffffffff, u64(fiat.u1(x10)))
+ x13, x14 := bits.sub_u64(x5, u64(0x0), u64(fiat.u1(x12)))
+ x15, x16 := bits.sub_u64(x7, 0xffffffff00000001, u64(fiat.u1(x14)))
+ _, x18 := bits.sub_u64(u64(fiat.u1(x8)), u64(0x0), u64(fiat.u1(x16)))
+ x19 := fiat.cmovznz_u64(fiat.u1(x18), x9, x1)
+ x20 := fiat.cmovznz_u64(fiat.u1(x18), x11, x3)
+ x21 := fiat.cmovznz_u64(fiat.u1(x18), x13, x5)
+ x22 := fiat.cmovznz_u64(fiat.u1(x18), x15, x7)
+ out1[0] = x19
+ out1[1] = x20
+ out1[2] = x21
+ out1[3] = x22
+}
+
+fe_sub :: proc "contextless" (out1, arg1, arg2: ^Montgomery_Domain_Field_Element) {
+ x1, x2 := bits.sub_u64(arg1[0], arg2[0], u64(0x0))
+ x3, x4 := bits.sub_u64(arg1[1], arg2[1], u64(fiat.u1(x2)))
+ x5, x6 := bits.sub_u64(arg1[2], arg2[2], u64(fiat.u1(x4)))
+ x7, x8 := bits.sub_u64(arg1[3], arg2[3], u64(fiat.u1(x6)))
+ x9 := fiat.cmovznz_u64(fiat.u1(x8), u64(0x0), 0xffffffffffffffff)
+ x10, x11 := bits.add_u64(x1, x9, u64(0x0))
+ x12, x13 := bits.add_u64(x3, (x9 & 0xffffffff), u64(fiat.u1(x11)))
+ x14, x15 := bits.add_u64(x5, u64(0x0), u64(fiat.u1(x13)))
+ x16, _ := bits.add_u64(x7, (x9 & 0xffffffff00000001), u64(fiat.u1(x15)))
+ out1[0] = x10
+ out1[1] = x12
+ out1[2] = x14
+ out1[3] = x16
+}
+
+fe_opp :: proc "contextless" (out1, arg1: ^Montgomery_Domain_Field_Element) {
+ x1, x2 := bits.sub_u64(u64(0x0), arg1[0], u64(0x0))
+ x3, x4 := bits.sub_u64(u64(0x0), arg1[1], u64(fiat.u1(x2)))
+ x5, x6 := bits.sub_u64(u64(0x0), arg1[2], u64(fiat.u1(x4)))
+ x7, x8 := bits.sub_u64(u64(0x0), arg1[3], u64(fiat.u1(x6)))
+ x9 := fiat.cmovznz_u64(fiat.u1(x8), u64(0x0), 0xffffffffffffffff)
+ x10, x11 := bits.add_u64(x1, x9, u64(0x0))
+ x12, x13 := bits.add_u64(x3, (x9 & 0xffffffff), u64(fiat.u1(x11)))
+ x14, x15 := bits.add_u64(x5, u64(0x0), u64(fiat.u1(x13)))
+ x16, _ := bits.add_u64(x7, (x9 & 0xffffffff00000001), u64(fiat.u1(x15)))
+ out1[0] = x10
+ out1[1] = x12
+ out1[2] = x14
+ out1[3] = x16
+}
+
+fe_one :: proc "contextless" (out1: ^Montgomery_Domain_Field_Element) {
+ out1[0] = 0x1
+ out1[1] = 0xffffffff00000000
+ out1[2] = 0xffffffffffffffff
+ out1[3] = 0xfffffffe
+}
+
+fe_non_zero :: proc "contextless" (arg1: ^Montgomery_Domain_Field_Element) -> u64 {
+ return arg1[0] | (arg1[1] | (arg1[2] | arg1[3]))
+}
+
+@(optimization_mode = "none")
+fe_cond_assign :: #force_no_inline proc "contextless" (
+ out1, arg1: ^Montgomery_Domain_Field_Element,
+ arg2: int,
+) {
+ x1 := fiat.cmovznz_u64(fiat.u1(arg2), out1[0], arg1[0])
+ x2 := fiat.cmovznz_u64(fiat.u1(arg2), out1[1], arg1[1])
+ x3 := fiat.cmovznz_u64(fiat.u1(arg2), out1[2], arg1[2])
+ x4 := fiat.cmovznz_u64(fiat.u1(arg2), out1[3], arg1[3])
+ out1[0] = x1
+ out1[1] = x2
+ out1[2] = x3
+ out1[3] = x4
+}
+
+fe_from_montgomery :: proc "contextless" (
+ out1: ^Non_Montgomery_Domain_Field_Element,
+ arg1: ^Montgomery_Domain_Field_Element,
+) {
+ x1 := arg1[0]
+ x3, x2 := bits.mul_u64(x1, 0xffffffff00000001)
+ x5, x4 := bits.mul_u64(x1, 0xffffffff)
+ x7, x6 := bits.mul_u64(x1, 0xffffffffffffffff)
+ x8, x9 := bits.add_u64(x7, x4, u64(0x0))
+ _, x11 := bits.add_u64(x1, x6, u64(0x0))
+ x12, x13 := bits.add_u64(u64(0x0), x8, u64(fiat.u1(x11)))
+ x14, x15 := bits.add_u64(x12, arg1[1], u64(0x0))
+ x17, x16 := bits.mul_u64(x14, 0xffffffff00000001)
+ x19, x18 := bits.mul_u64(x14, 0xffffffff)
+ x21, x20 := bits.mul_u64(x14, 0xffffffffffffffff)
+ x22, x23 := bits.add_u64(x21, x18, u64(0x0))
+ _, x25 := bits.add_u64(x14, x20, u64(0x0))
+ x26, x27 := bits.add_u64((u64(fiat.u1(x15)) + (u64(fiat.u1(x13)) + (u64(fiat.u1(x9)) + x5))), x22, u64(fiat.u1(x25)))
+ x28, x29 := bits.add_u64(x2, (u64(fiat.u1(x23)) + x19), u64(fiat.u1(x27)))
+ x30, x31 := bits.add_u64(x3, x16, u64(fiat.u1(x29)))
+ x32, x33 := bits.add_u64(x26, arg1[2], u64(0x0))
+ x34, x35 := bits.add_u64(x28, u64(0x0), u64(fiat.u1(x33)))
+ x36, x37 := bits.add_u64(x30, u64(0x0), u64(fiat.u1(x35)))
+ x39, x38 := bits.mul_u64(x32, 0xffffffff00000001)
+ x41, x40 := bits.mul_u64(x32, 0xffffffff)
+ x43, x42 := bits.mul_u64(x32, 0xffffffffffffffff)
+ x44, x45 := bits.add_u64(x43, x40, u64(0x0))
+ _, x47 := bits.add_u64(x32, x42, u64(0x0))
+ x48, x49 := bits.add_u64(x34, x44, u64(fiat.u1(x47)))
+ x50, x51 := bits.add_u64(x36, (u64(fiat.u1(x45)) + x41), u64(fiat.u1(x49)))
+ x52, x53 := bits.add_u64((u64(fiat.u1(x37)) + (u64(fiat.u1(x31)) + x17)), x38, u64(fiat.u1(x51)))
+ x54, x55 := bits.add_u64(x48, arg1[3], u64(0x0))
+ x56, x57 := bits.add_u64(x50, u64(0x0), u64(fiat.u1(x55)))
+ x58, x59 := bits.add_u64(x52, u64(0x0), u64(fiat.u1(x57)))
+ x61, x60 := bits.mul_u64(x54, 0xffffffff00000001)
+ x63, x62 := bits.mul_u64(x54, 0xffffffff)
+ x65, x64 := bits.mul_u64(x54, 0xffffffffffffffff)
+ x66, x67 := bits.add_u64(x65, x62, u64(0x0))
+ _, x69 := bits.add_u64(x54, x64, u64(0x0))
+ x70, x71 := bits.add_u64(x56, x66, u64(fiat.u1(x69)))
+ x72, x73 := bits.add_u64(x58, (u64(fiat.u1(x67)) + x63), u64(fiat.u1(x71)))
+ x74, x75 := bits.add_u64((u64(fiat.u1(x59)) + (u64(fiat.u1(x53)) + x39)), x60, u64(fiat.u1(x73)))
+ x76 := (u64(fiat.u1(x75)) + x61)
+ x77, x78 := bits.sub_u64(x70, 0xffffffffffffffff, u64(0x0))
+ x79, x80 := bits.sub_u64(x72, 0xffffffff, u64(fiat.u1(x78)))
+ x81, x82 := bits.sub_u64(x74, u64(0x0), u64(fiat.u1(x80)))
+ x83, x84 := bits.sub_u64(x76, 0xffffffff00000001, u64(fiat.u1(x82)))
+ _, x86 := bits.sub_u64(u64(0x0), u64(0x0), u64(fiat.u1(x84)))
+ x87 := fiat.cmovznz_u64(fiat.u1(x86), x77, x70)
+ x88 := fiat.cmovznz_u64(fiat.u1(x86), x79, x72)
+ x89 := fiat.cmovznz_u64(fiat.u1(x86), x81, x74)
+ x90 := fiat.cmovznz_u64(fiat.u1(x86), x83, x76)
+ out1[0] = x87
+ out1[1] = x88
+ out1[2] = x89
+ out1[3] = x90
+}
+
+fe_to_montgomery :: proc "contextless" (
+ out1: ^Montgomery_Domain_Field_Element,
+ arg1: ^Non_Montgomery_Domain_Field_Element,
+) {
+ x1 := arg1[1]
+ x2 := arg1[2]
+ x3 := arg1[3]
+ x4 := arg1[0]
+ x6, x5 := bits.mul_u64(x4, 0x4fffffffd)
+ x8, x7 := bits.mul_u64(x4, 0xfffffffffffffffe)
+ x10, x9 := bits.mul_u64(x4, 0xfffffffbffffffff)
+ x12, x11 := bits.mul_u64(x4, 0x3)
+ x13, x14 := bits.add_u64(x12, x9, u64(0x0))
+ x15, x16 := bits.add_u64(x10, x7, u64(fiat.u1(x14)))
+ x17, x18 := bits.add_u64(x8, x5, u64(fiat.u1(x16)))
+ x20, x19 := bits.mul_u64(x11, 0xffffffff00000001)
+ x22, x21 := bits.mul_u64(x11, 0xffffffff)
+ x24, x23 := bits.mul_u64(x11, 0xffffffffffffffff)
+ x25, x26 := bits.add_u64(x24, x21, u64(0x0))
+ _, x28 := bits.add_u64(x11, x23, u64(0x0))
+ x29, x30 := bits.add_u64(x13, x25, u64(fiat.u1(x28)))
+ x31, x32 := bits.add_u64(x15, (u64(fiat.u1(x26)) + x22), u64(fiat.u1(x30)))
+ x33, x34 := bits.add_u64(x17, x19, u64(fiat.u1(x32)))
+ x35, x36 := bits.add_u64((u64(fiat.u1(x18)) + x6), x20, u64(fiat.u1(x34)))
+ x38, x37 := bits.mul_u64(x1, 0x4fffffffd)
+ x40, x39 := bits.mul_u64(x1, 0xfffffffffffffffe)
+ x42, x41 := bits.mul_u64(x1, 0xfffffffbffffffff)
+ x44, x43 := bits.mul_u64(x1, 0x3)
+ x45, x46 := bits.add_u64(x44, x41, u64(0x0))
+ x47, x48 := bits.add_u64(x42, x39, u64(fiat.u1(x46)))
+ x49, x50 := bits.add_u64(x40, x37, u64(fiat.u1(x48)))
+ x51, x52 := bits.add_u64(x29, x43, u64(0x0))
+ x53, x54 := bits.add_u64(x31, x45, u64(fiat.u1(x52)))
+ x55, x56 := bits.add_u64(x33, x47, u64(fiat.u1(x54)))
+ x57, x58 := bits.add_u64(x35, x49, u64(fiat.u1(x56)))
+ x60, x59 := bits.mul_u64(x51, 0xffffffff00000001)
+ x62, x61 := bits.mul_u64(x51, 0xffffffff)
+ x64, x63 := bits.mul_u64(x51, 0xffffffffffffffff)
+ x65, x66 := bits.add_u64(x64, x61, u64(0x0))
+ _, x68 := bits.add_u64(x51, x63, u64(0x0))
+ x69, x70 := bits.add_u64(x53, x65, u64(fiat.u1(x68)))
+ x71, x72 := bits.add_u64(x55, (u64(fiat.u1(x66)) + x62), u64(fiat.u1(x70)))
+ x73, x74 := bits.add_u64(x57, x59, u64(fiat.u1(x72)))
+ x75, x76 := bits.add_u64(((u64(fiat.u1(x58)) + u64(fiat.u1(x36))) + (u64(fiat.u1(x50)) + x38)), x60, u64(fiat.u1(x74)))
+ x78, x77 := bits.mul_u64(x2, 0x4fffffffd)
+ x80, x79 := bits.mul_u64(x2, 0xfffffffffffffffe)
+ x82, x81 := bits.mul_u64(x2, 0xfffffffbffffffff)
+ x84, x83 := bits.mul_u64(x2, 0x3)
+ x85, x86 := bits.add_u64(x84, x81, u64(0x0))
+ x87, x88 := bits.add_u64(x82, x79, u64(fiat.u1(x86)))
+ x89, x90 := bits.add_u64(x80, x77, u64(fiat.u1(x88)))
+ x91, x92 := bits.add_u64(x69, x83, u64(0x0))
+ x93, x94 := bits.add_u64(x71, x85, u64(fiat.u1(x92)))
+ x95, x96 := bits.add_u64(x73, x87, u64(fiat.u1(x94)))
+ x97, x98 := bits.add_u64(x75, x89, u64(fiat.u1(x96)))
+ x100, x99 := bits.mul_u64(x91, 0xffffffff00000001)
+ x102, x101 := bits.mul_u64(x91, 0xffffffff)
+ x104, x103 := bits.mul_u64(x91, 0xffffffffffffffff)
+ x105, x106 := bits.add_u64(x104, x101, u64(0x0))
+ _, x108 := bits.add_u64(x91, x103, u64(0x0))
+ x109, x110 := bits.add_u64(x93, x105, u64(fiat.u1(x108)))
+ x111, x112 := bits.add_u64(x95, (u64(fiat.u1(x106)) + x102), u64(fiat.u1(x110)))
+ x113, x114 := bits.add_u64(x97, x99, u64(fiat.u1(x112)))
+ x115, x116 := bits.add_u64(((u64(fiat.u1(x98)) + u64(fiat.u1(x76))) + (u64(fiat.u1(x90)) + x78)), x100, u64(fiat.u1(x114)))
+ x118, x117 := bits.mul_u64(x3, 0x4fffffffd)
+ x120, x119 := bits.mul_u64(x3, 0xfffffffffffffffe)
+ x122, x121 := bits.mul_u64(x3, 0xfffffffbffffffff)
+ x124, x123 := bits.mul_u64(x3, 0x3)
+ x125, x126 := bits.add_u64(x124, x121, u64(0x0))
+ x127, x128 := bits.add_u64(x122, x119, u64(fiat.u1(x126)))
+ x129, x130 := bits.add_u64(x120, x117, u64(fiat.u1(x128)))
+ x131, x132 := bits.add_u64(x109, x123, u64(0x0))
+ x133, x134 := bits.add_u64(x111, x125, u64(fiat.u1(x132)))
+ x135, x136 := bits.add_u64(x113, x127, u64(fiat.u1(x134)))
+ x137, x138 := bits.add_u64(x115, x129, u64(fiat.u1(x136)))
+ x140, x139 := bits.mul_u64(x131, 0xffffffff00000001)
+ x142, x141 := bits.mul_u64(x131, 0xffffffff)
+ x144, x143 := bits.mul_u64(x131, 0xffffffffffffffff)
+ x145, x146 := bits.add_u64(x144, x141, u64(0x0))
+ _, x148 := bits.add_u64(x131, x143, u64(0x0))
+ x149, x150 := bits.add_u64(x133, x145, u64(fiat.u1(x148)))
+ x151, x152 := bits.add_u64(x135, (u64(fiat.u1(x146)) + x142), u64(fiat.u1(x150)))
+ x153, x154 := bits.add_u64(x137, x139, u64(fiat.u1(x152)))
+ x155, x156 := bits.add_u64(((u64(fiat.u1(x138)) + u64(fiat.u1(x116))) + (u64(fiat.u1(x130)) + x118)), x140, u64(fiat.u1(x154)))
+ x157, x158 := bits.sub_u64(x149, 0xffffffffffffffff, u64(0x0))
+ x159, x160 := bits.sub_u64(x151, 0xffffffff, u64(fiat.u1(x158)))
+ x161, x162 := bits.sub_u64(x153, u64(0x0), u64(fiat.u1(x160)))
+ x163, x164 := bits.sub_u64(x155, 0xffffffff00000001, u64(fiat.u1(x162)))
+ _, x166 := bits.sub_u64(u64(fiat.u1(x156)), u64(0x0), u64(fiat.u1(x164)))
+ x167 := fiat.cmovznz_u64(fiat.u1(x166), x157, x149)
+ x168 := fiat.cmovznz_u64(fiat.u1(x166), x159, x151)
+ x169 := fiat.cmovznz_u64(fiat.u1(x166), x161, x153)
+ x170 := fiat.cmovznz_u64(fiat.u1(x166), x163, x155)
+ out1[0] = x167
+ out1[1] = x168
+ out1[2] = x169
+ out1[3] = x170
+}
diff --git a/core/crypto/_fiat/field_scalar25519/field.odin b/core/crypto/_fiat/field_scalar25519/field.odin
index 933637c54..96b279ce7 100644
--- a/core/crypto/_fiat/field_scalar25519/field.odin
+++ b/core/crypto/_fiat/field_scalar25519/field.odin
@@ -1,5 +1,6 @@
package field_scalar25519
+import subtle "core:crypto/_subtle"
import "core:encoding/endian"
import "core:math/bits"
import "core:mem"
@@ -121,13 +122,11 @@ fe_equal :: proc "contextless" (arg1, arg2: ^Montgomery_Domain_Field_Element) ->
tmp: Montgomery_Domain_Field_Element
fe_sub(&tmp, arg1, arg2)
- // This will only underflow iff arg1 == arg2, and we return the borrow,
- // which will be 1.
- _, borrow := bits.sub_u64(fe_non_zero(&tmp), 1, 0)
+ is_eq := subtle.eq(fe_non_zero(&tmp), 0)
fe_clear(&tmp)
- return int(borrow)
+ return int(is_eq)
}
fe_zero :: proc "contextless" (out1: ^Montgomery_Domain_Field_Element) {
diff --git a/core/crypto/_fiat/field_scalarp256r1/field.odin b/core/crypto/_fiat/field_scalarp256r1/field.odin
new file mode 100644
index 000000000..73c01fb46
--- /dev/null
+++ b/core/crypto/_fiat/field_scalarp256r1/field.odin
@@ -0,0 +1,210 @@
+package field_scalarp256r1
+
+import subtle "core:crypto/_subtle"
+import "core:encoding/endian"
+import "core:math/bits"
+import "core:mem"
+
+@(private, rodata)
+TWO_192 := Montgomery_Domain_Field_Element{
+ 2482910415990817935,
+ 2879494685571067143,
+ 8732918506673730078,
+ 85565669603516024,
+}
+@(private, rodata)
+TWO_384 := Montgomery_Domain_Field_Element{
+ 2127524300190691059,
+ 17014302137236182484,
+ 16604910261202196099,
+ 3621421107472562910,
+}
+// 2^384 % p (From sage)
+// 0x431905529c0166ce652e96b7ccca0a99679b73e19ad16947f01cf013fc632551
+
+fe_clear :: proc "contextless" (arg1: ^Montgomery_Domain_Field_Element) {
+ mem.zero_explicit(arg1, size_of(Montgomery_Domain_Field_Element))
+}
+
+fe_clear_vec :: proc "contextless" (
+ arg1: []^Montgomery_Domain_Field_Element,
+) {
+ for fe in arg1 {
+ fe_clear(fe)
+ }
+}
+
+fe_from_bytes :: proc "contextless" (
+ out1: ^Montgomery_Domain_Field_Element,
+ arg1: []byte,
+) -> bool {
+ ensure_contextless(len(out1) <= 64, "p256r1: invalid scalar input buffer")
+
+ is_canonical := false
+ s_len := len(arg1)
+ switch {
+ case s_len < 32:
+ // No way this can be greater than the order.
+ fe_unchecked_set(out1, arg1)
+ is_canonical = true
+ case s_len == 32:
+ // It is quite likely that a reduction mod p is required,
+ // as the order of the curve is sufficiently smaller than
+ // 2^256-1, so just check if we actually needed to reduced
+ // and do the reduction anyway, so that things that require
+ // canonical scalars can reject non-canonical encodings.
+ is_canonical = fe_is_canonical(arg1)
+ fallthrough
+ case:
+ // Use Frank Denis' trick, as documented by Filippo Valsorda
+ // at https://words.filippo.io/dispatches/wide-reduction/
+ //
+ // "I represent the value as a+b*2^192+c*2^384"
+ //
+ // Note: Omitting the `c` computation is fine as, reduction
+ // being length dependent provides no useful timing information.
+
+ // Zero extend to 512-bits.
+ src_512: [64]byte
+ copy(src_512[64-s_len:], arg1)
+ defer mem.zero_explicit(&src_512, size_of(src_512))
+
+ fe_unchecked_set(out1, src_512[40:]) // a
+ b: Montgomery_Domain_Field_Element
+ fe_unchecked_set(&b, src_512[16:40]) // b
+
+ fe_mul(&b, &b, &TWO_192)
+ fe_add(out1, out1, &b)
+ if s_len >= 48 {
+ c: Montgomery_Domain_Field_Element
+ fe_unchecked_set(&c, src_512[:16]) // c
+ fe_mul(&c, &c, &TWO_384)
+ fe_add(out1, out1, &c)
+
+ fe_clear(&c)
+ }
+
+ fe_clear(&b)
+ }
+
+ return !is_canonical
+}
+
+@(private)
+fe_is_canonical :: proc "contextless" (arg1: []byte) -> bool {
+ _, borrow := bits.sub_u64(ELL[0] - 1, endian.unchecked_get_u64be(arg1[24:]), 0)
+ _, borrow = bits.sub_u64(ELL[1], endian.unchecked_get_u64be(arg1[16:]), borrow)
+ _, borrow = bits.sub_u64(ELL[2], endian.unchecked_get_u64be(arg1[8:]), borrow)
+ _, borrow = bits.sub_u64(ELL[3], endian.unchecked_get_u64be(arg1[0:]), borrow)
+ return borrow == 0
+}
+
+@(private)
+fe_unchecked_set :: proc "contextless" (out1: ^Montgomery_Domain_Field_Element, arg1: []byte) {
+ arg1_256: [32]byte
+ defer mem.zero_explicit(&arg1_256, size_of(arg1_256))
+ copy(arg1_256[32-len(arg1):], arg1)
+
+ tmp := Non_Montgomery_Domain_Field_Element {
+ endian.unchecked_get_u64be(arg1_256[24:]),
+ endian.unchecked_get_u64be(arg1_256[16:]),
+ endian.unchecked_get_u64be(arg1_256[8:]),
+ endian.unchecked_get_u64be(arg1_256[0:]),
+ }
+ defer mem.zero_explicit(&tmp, size_of(tmp))
+
+ fe_to_montgomery(out1, &tmp)
+}
+
+fe_to_bytes :: proc "contextless" (out1: []byte, arg1: ^Montgomery_Domain_Field_Element) {
+ ensure_contextless(len(out1) == 32, "p256r1: invalid scalar output buffer")
+
+ tmp: Non_Montgomery_Domain_Field_Element
+ fe_from_montgomery(&tmp, arg1)
+
+ // Note: Likewise, output in big-endian.
+ endian.unchecked_put_u64be(out1[24:], tmp[0])
+ endian.unchecked_put_u64be(out1[16:], tmp[1])
+ endian.unchecked_put_u64be(out1[8:], tmp[2])
+ endian.unchecked_put_u64be(out1[0:], tmp[3])
+
+ mem.zero_explicit(&tmp, size_of(tmp))
+}
+
+fe_equal :: proc "contextless" (arg1, arg2: ^Montgomery_Domain_Field_Element) -> int {
+ tmp: Montgomery_Domain_Field_Element
+ fe_sub(&tmp, arg1, arg2)
+
+ is_eq := subtle.u64_is_zero(fe_non_zero(&tmp))
+
+ fe_clear(&tmp)
+
+ return int(is_eq)
+}
+
+fe_is_odd :: proc "contextless" (arg1: ^Montgomery_Domain_Field_Element) -> int {
+ tmp: Non_Montgomery_Domain_Field_Element
+ defer mem.zero_explicit(&tmp, size_of(tmp))
+
+ fe_from_montgomery(&tmp, arg1)
+ return int(tmp[0] & 1)
+}
+
+fe_zero :: proc "contextless" (out1: ^Montgomery_Domain_Field_Element) {
+ out1[0] = 0
+ out1[1] = 0
+ out1[2] = 0
+ out1[3] = 0
+}
+
+fe_set :: proc "contextless" (out1, arg1: ^Montgomery_Domain_Field_Element) {
+ x1 := arg1[0]
+ x2 := arg1[1]
+ x3 := arg1[2]
+ x4 := arg1[3]
+ out1[0] = x1
+ out1[1] = x2
+ out1[2] = x3
+ out1[3] = x4
+}
+
+@(optimization_mode = "none")
+fe_cond_swap :: #force_no_inline proc "contextless" (out1, out2: ^Montgomery_Domain_Field_Element, arg1: int) {
+ mask := (u64(arg1) * 0xffffffffffffffff)
+ x := (out1[0] ~ out2[0]) & mask
+ x1, y1 := out1[0] ~ x, out2[0] ~ x
+ x = (out1[1] ~ out2[1]) & mask
+ x2, y2 := out1[1] ~ x, out2[1] ~ x
+ x = (out1[2] ~ out2[2]) & mask
+ x3, y3 := out1[2] ~ x, out2[2] ~ x
+ x = (out1[3] ~ out2[3]) & mask
+ x4, y4 := out1[3] ~ x, out2[3] ~ x
+ out1[0], out2[0] = x1, y1
+ out1[1], out2[1] = x2, y2
+ out1[2], out2[2] = x3, y3
+ out1[3], out2[3] = x4, y4
+}
+
+@(optimization_mode = "none")
+fe_cond_select :: #force_no_inline proc "contextless" (
+ out1, arg1, arg2: ^Montgomery_Domain_Field_Element,
+ arg3: int,
+) {
+ mask := (u64(arg3) * 0xffffffffffffffff)
+ x1 := ((mask & arg2[0]) | ((~mask) & arg1[0]))
+ x2 := ((mask & arg2[1]) | ((~mask) & arg1[1]))
+ x3 := ((mask & arg2[2]) | ((~mask) & arg1[2]))
+ x4 := ((mask & arg2[3]) | ((~mask) & arg1[3]))
+ out1[0] = x1
+ out1[1] = x2
+ out1[2] = x3
+ out1[3] = x4
+}
+
+fe_cond_negate :: proc "contextless" (out1, arg1: ^Montgomery_Domain_Field_Element, ctrl: int) {
+ tmp1: Montgomery_Domain_Field_Element = ---
+ fe_opp(&tmp1, arg1)
+ fe_cond_select(out1, arg1, &tmp1, ctrl)
+
+ fe_clear(&tmp1)
+}
diff --git a/core/crypto/_fiat/field_scalarp256r1/field64.odin b/core/crypto/_fiat/field_scalarp256r1/field64.odin
new file mode 100644
index 000000000..4217374a7
--- /dev/null
+++ b/core/crypto/_fiat/field_scalarp256r1/field64.odin
@@ -0,0 +1,569 @@
+// The BSD 1-Clause License (BSD-1-Clause)
+//
+// Copyright (c) 2015-2020 the fiat-crypto authors (see the AUTHORS file)
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// THIS SOFTWARE IS PROVIDED BY the fiat-crypto authors "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design,
+// Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package field_scalarp256r1
+
+// The file provides arithmetic on the field Z/(2^256 - 2^224 + 2^192 -
+// 89188191075325690597107910205041859247) using a 64-bit Montgomery form
+// internal representation. It is derived primarily from the machine
+// generated Golang output from the fiat-crypto project.
+//
+// While the base implementation is provably correct, this implementation
+// makes no such claims as the port and optimizations were done by hand.
+//
+// WARNING: While big-endian is the common representation used for this
+// curve, the fiat output uses least-significant-limb first.
+
+import fiat "core:crypto/_fiat"
+import "core:math/bits"
+
+// ELL is the saturated representation of the field order, least-significant
+// limb first.
+ELL :: [4]u64{0xf3b9cac2fc632551, 0xbce6faada7179e84, 0xffffffffffffffff, 0xffffffff00000000}
+
+Montgomery_Domain_Field_Element :: distinct [4]u64
+Non_Montgomery_Domain_Field_Element :: distinct [4]u64
+
+fe_mul :: proc "contextless" (out1, arg1, arg2: ^Montgomery_Domain_Field_Element) {
+ x1 := arg1[1]
+ x2 := arg1[2]
+ x3 := arg1[3]
+ x4 := arg1[0]
+ x6, x5 := bits.mul_u64(x4, arg2[3])
+ x8, x7 := bits.mul_u64(x4, arg2[2])
+ x10, x9 := bits.mul_u64(x4, arg2[1])
+ x12, x11 := bits.mul_u64(x4, arg2[0])
+ x13, x14 := bits.add_u64(x12, x9, u64(0x0))
+ x15, x16 := bits.add_u64(x10, x7, u64(fiat.u1(x14)))
+ x17, x18 := bits.add_u64(x8, x5, u64(fiat.u1(x16)))
+ x19 := (u64(fiat.u1(x18)) + x6)
+ _, x20 := bits.mul_u64(x11, 0xccd1c8aaee00bc4f)
+ x23, x22 := bits.mul_u64(x20, 0xffffffff00000000)
+ x25, x24 := bits.mul_u64(x20, 0xffffffffffffffff)
+ x27, x26 := bits.mul_u64(x20, 0xbce6faada7179e84)
+ x29, x28 := bits.mul_u64(x20, 0xf3b9cac2fc632551)
+ x30, x31 := bits.add_u64(x29, x26, u64(0x0))
+ x32, x33 := bits.add_u64(x27, x24, u64(fiat.u1(x31)))
+ x34, x35 := bits.add_u64(x25, x22, u64(fiat.u1(x33)))
+ x36 := (u64(fiat.u1(x35)) + x23)
+ _, x38 := bits.add_u64(x11, x28, u64(0x0))
+ x39, x40 := bits.add_u64(x13, x30, u64(fiat.u1(x38)))
+ x41, x42 := bits.add_u64(x15, x32, u64(fiat.u1(x40)))
+ x43, x44 := bits.add_u64(x17, x34, u64(fiat.u1(x42)))
+ x45, x46 := bits.add_u64(x19, x36, u64(fiat.u1(x44)))
+ x48, x47 := bits.mul_u64(x1, arg2[3])
+ x50, x49 := bits.mul_u64(x1, arg2[2])
+ x52, x51 := bits.mul_u64(x1, arg2[1])
+ x54, x53 := bits.mul_u64(x1, arg2[0])
+ x55, x56 := bits.add_u64(x54, x51, u64(0x0))
+ x57, x58 := bits.add_u64(x52, x49, u64(fiat.u1(x56)))
+ x59, x60 := bits.add_u64(x50, x47, u64(fiat.u1(x58)))
+ x61 := (u64(fiat.u1(x60)) + x48)
+ x62, x63 := bits.add_u64(x39, x53, u64(0x0))
+ x64, x65 := bits.add_u64(x41, x55, u64(fiat.u1(x63)))
+ x66, x67 := bits.add_u64(x43, x57, u64(fiat.u1(x65)))
+ x68, x69 := bits.add_u64(x45, x59, u64(fiat.u1(x67)))
+ x70, x71 := bits.add_u64(u64(fiat.u1(x46)), x61, u64(fiat.u1(x69)))
+ _, x72 := bits.mul_u64(x62, 0xccd1c8aaee00bc4f)
+ x75, x74 := bits.mul_u64(x72, 0xffffffff00000000)
+ x77, x76 := bits.mul_u64(x72, 0xffffffffffffffff)
+ x79, x78 := bits.mul_u64(x72, 0xbce6faada7179e84)
+ x81, x80 := bits.mul_u64(x72, 0xf3b9cac2fc632551)
+ x82, x83 := bits.add_u64(x81, x78, u64(0x0))
+ x84, x85 := bits.add_u64(x79, x76, u64(fiat.u1(x83)))
+ x86, x87 := bits.add_u64(x77, x74, u64(fiat.u1(x85)))
+ x88 := (u64(fiat.u1(x87)) + x75)
+ _, x90 := bits.add_u64(x62, x80, u64(0x0))
+ x91, x92 := bits.add_u64(x64, x82, u64(fiat.u1(x90)))
+ x93, x94 := bits.add_u64(x66, x84, u64(fiat.u1(x92)))
+ x95, x96 := bits.add_u64(x68, x86, u64(fiat.u1(x94)))
+ x97, x98 := bits.add_u64(x70, x88, u64(fiat.u1(x96)))
+ x99 := (u64(fiat.u1(x98)) + u64(fiat.u1(x71)))
+ x101, x100 := bits.mul_u64(x2, arg2[3])
+ x103, x102 := bits.mul_u64(x2, arg2[2])
+ x105, x104 := bits.mul_u64(x2, arg2[1])
+ x107, x106 := bits.mul_u64(x2, arg2[0])
+ x108, x109 := bits.add_u64(x107, x104, u64(0x0))
+ x110, x111 := bits.add_u64(x105, x102, u64(fiat.u1(x109)))
+ x112, x113 := bits.add_u64(x103, x100, u64(fiat.u1(x111)))
+ x114 := (u64(fiat.u1(x113)) + x101)
+ x115, x116 := bits.add_u64(x91, x106, u64(0x0))
+ x117, x118 := bits.add_u64(x93, x108, u64(fiat.u1(x116)))
+ x119, x120 := bits.add_u64(x95, x110, u64(fiat.u1(x118)))
+ x121, x122 := bits.add_u64(x97, x112, u64(fiat.u1(x120)))
+ x123, x124 := bits.add_u64(x99, x114, u64(fiat.u1(x122)))
+ _, x125 := bits.mul_u64(x115, 0xccd1c8aaee00bc4f)
+ x128, x127 := bits.mul_u64(x125, 0xffffffff00000000)
+ x130, x129 := bits.mul_u64(x125, 0xffffffffffffffff)
+ x132, x131 := bits.mul_u64(x125, 0xbce6faada7179e84)
+ x134, x133 := bits.mul_u64(x125, 0xf3b9cac2fc632551)
+ x135, x136 := bits.add_u64(x134, x131, u64(0x0))
+ x137, x138 := bits.add_u64(x132, x129, u64(fiat.u1(x136)))
+ x139, x140 := bits.add_u64(x130, x127, u64(fiat.u1(x138)))
+ x141 := (u64(fiat.u1(x140)) + x128)
+ _, x143 := bits.add_u64(x115, x133, u64(0x0))
+ x144, x145 := bits.add_u64(x117, x135, u64(fiat.u1(x143)))
+ x146, x147 := bits.add_u64(x119, x137, u64(fiat.u1(x145)))
+ x148, x149 := bits.add_u64(x121, x139, u64(fiat.u1(x147)))
+ x150, x151 := bits.add_u64(x123, x141, u64(fiat.u1(x149)))
+ x152 := (u64(fiat.u1(x151)) + u64(fiat.u1(x124)))
+ x154, x153 := bits.mul_u64(x3, arg2[3])
+ x156, x155 := bits.mul_u64(x3, arg2[2])
+ x158, x157 := bits.mul_u64(x3, arg2[1])
+ x160, x159 := bits.mul_u64(x3, arg2[0])
+ x161, x162 := bits.add_u64(x160, x157, u64(0x0))
+ x163, x164 := bits.add_u64(x158, x155, u64(fiat.u1(x162)))
+ x165, x166 := bits.add_u64(x156, x153, u64(fiat.u1(x164)))
+ x167 := (u64(fiat.u1(x166)) + x154)
+ x168, x169 := bits.add_u64(x144, x159, u64(0x0))
+ x170, x171 := bits.add_u64(x146, x161, u64(fiat.u1(x169)))
+ x172, x173 := bits.add_u64(x148, x163, u64(fiat.u1(x171)))
+ x174, x175 := bits.add_u64(x150, x165, u64(fiat.u1(x173)))
+ x176, x177 := bits.add_u64(x152, x167, u64(fiat.u1(x175)))
+ _, x178 := bits.mul_u64(x168, 0xccd1c8aaee00bc4f)
+ x181, x180 := bits.mul_u64(x178, 0xffffffff00000000)
+ x183, x182 := bits.mul_u64(x178, 0xffffffffffffffff)
+ x185, x184 := bits.mul_u64(x178, 0xbce6faada7179e84)
+ x187, x186 := bits.mul_u64(x178, 0xf3b9cac2fc632551)
+ x188, x189 := bits.add_u64(x187, x184, u64(0x0))
+ x190, x191 := bits.add_u64(x185, x182, u64(fiat.u1(x189)))
+ x192, x193 := bits.add_u64(x183, x180, u64(fiat.u1(x191)))
+ x194 := (u64(fiat.u1(x193)) + x181)
+ _, x196 := bits.add_u64(x168, x186, u64(0x0))
+ x197, x198 := bits.add_u64(x170, x188, u64(fiat.u1(x196)))
+ x199, x200 := bits.add_u64(x172, x190, u64(fiat.u1(x198)))
+ x201, x202 := bits.add_u64(x174, x192, u64(fiat.u1(x200)))
+ x203, x204 := bits.add_u64(x176, x194, u64(fiat.u1(x202)))
+ x205 := (u64(fiat.u1(x204)) + u64(fiat.u1(x177)))
+ x206, x207 := bits.sub_u64(x197, 0xf3b9cac2fc632551, u64(0x0))
+ x208, x209 := bits.sub_u64(x199, 0xbce6faada7179e84, u64(fiat.u1(x207)))
+ x210, x211 := bits.sub_u64(x201, 0xffffffffffffffff, u64(fiat.u1(x209)))
+ x212, x213 := bits.sub_u64(x203, 0xffffffff00000000, u64(fiat.u1(x211)))
+ _, x215 := bits.sub_u64(x205, u64(0x0), u64(fiat.u1(x213)))
+ x216 := fiat.cmovznz_u64(fiat.u1(x215), x206, x197)
+ x217 := fiat.cmovznz_u64(fiat.u1(x215), x208, x199)
+ x218 := fiat.cmovznz_u64(fiat.u1(x215), x210, x201)
+ x219 := fiat.cmovznz_u64(fiat.u1(x215), x212, x203)
+ out1[0] = x216
+ out1[1] = x217
+ out1[2] = x218
+ out1[3] = x219
+}
+
+fe_square :: proc "contextless" (out1, arg1: ^Montgomery_Domain_Field_Element) {
+ x1 := arg1[1]
+ x2 := arg1[2]
+ x3 := arg1[3]
+ x4 := arg1[0]
+ x6, x5 := bits.mul_u64(x4, arg1[3])
+ x8, x7 := bits.mul_u64(x4, arg1[2])
+ x10, x9 := bits.mul_u64(x4, arg1[1])
+ x12, x11 := bits.mul_u64(x4, arg1[0])
+ x13, x14 := bits.add_u64(x12, x9, u64(0x0))
+ x15, x16 := bits.add_u64(x10, x7, u64(fiat.u1(x14)))
+ x17, x18 := bits.add_u64(x8, x5, u64(fiat.u1(x16)))
+ x19 := (u64(fiat.u1(x18)) + x6)
+ _, x20 := bits.mul_u64(x11, 0xccd1c8aaee00bc4f)
+ x23, x22 := bits.mul_u64(x20, 0xffffffff00000000)
+ x25, x24 := bits.mul_u64(x20, 0xffffffffffffffff)
+ x27, x26 := bits.mul_u64(x20, 0xbce6faada7179e84)
+ x29, x28 := bits.mul_u64(x20, 0xf3b9cac2fc632551)
+ x30, x31 := bits.add_u64(x29, x26, u64(0x0))
+ x32, x33 := bits.add_u64(x27, x24, u64(fiat.u1(x31)))
+ x34, x35 := bits.add_u64(x25, x22, u64(fiat.u1(x33)))
+ x36 := (u64(fiat.u1(x35)) + x23)
+ _, x38 := bits.add_u64(x11, x28, u64(0x0))
+ x39, x40 := bits.add_u64(x13, x30, u64(fiat.u1(x38)))
+ x41, x42 := bits.add_u64(x15, x32, u64(fiat.u1(x40)))
+ x43, x44 := bits.add_u64(x17, x34, u64(fiat.u1(x42)))
+ x45, x46 := bits.add_u64(x19, x36, u64(fiat.u1(x44)))
+ x48, x47 := bits.mul_u64(x1, arg1[3])
+ x50, x49 := bits.mul_u64(x1, arg1[2])
+ x52, x51 := bits.mul_u64(x1, arg1[1])
+ x54, x53 := bits.mul_u64(x1, arg1[0])
+ x55, x56 := bits.add_u64(x54, x51, u64(0x0))
+ x57, x58 := bits.add_u64(x52, x49, u64(fiat.u1(x56)))
+ x59, x60 := bits.add_u64(x50, x47, u64(fiat.u1(x58)))
+ x61 := (u64(fiat.u1(x60)) + x48)
+ x62, x63 := bits.add_u64(x39, x53, u64(0x0))
+ x64, x65 := bits.add_u64(x41, x55, u64(fiat.u1(x63)))
+ x66, x67 := bits.add_u64(x43, x57, u64(fiat.u1(x65)))
+ x68, x69 := bits.add_u64(x45, x59, u64(fiat.u1(x67)))
+ x70, x71 := bits.add_u64(u64(fiat.u1(x46)), x61, u64(fiat.u1(x69)))
+ _, x72 := bits.mul_u64(x62, 0xccd1c8aaee00bc4f)
+ x75, x74 := bits.mul_u64(x72, 0xffffffff00000000)
+ x77, x76 := bits.mul_u64(x72, 0xffffffffffffffff)
+ x79, x78 := bits.mul_u64(x72, 0xbce6faada7179e84)
+ x81, x80 := bits.mul_u64(x72, 0xf3b9cac2fc632551)
+ x82, x83 := bits.add_u64(x81, x78, u64(0x0))
+ x84, x85 := bits.add_u64(x79, x76, u64(fiat.u1(x83)))
+ x86, x87 := bits.add_u64(x77, x74, u64(fiat.u1(x85)))
+ x88 := (u64(fiat.u1(x87)) + x75)
+ _, x90 := bits.add_u64(x62, x80, u64(0x0))
+ x91, x92 := bits.add_u64(x64, x82, u64(fiat.u1(x90)))
+ x93, x94 := bits.add_u64(x66, x84, u64(fiat.u1(x92)))
+ x95, x96 := bits.add_u64(x68, x86, u64(fiat.u1(x94)))
+ x97, x98 := bits.add_u64(x70, x88, u64(fiat.u1(x96)))
+ x99 := (u64(fiat.u1(x98)) + u64(fiat.u1(x71)))
+ x101, x100 := bits.mul_u64(x2, arg1[3])
+ x103, x102 := bits.mul_u64(x2, arg1[2])
+ x105, x104 := bits.mul_u64(x2, arg1[1])
+ x107, x106 := bits.mul_u64(x2, arg1[0])
+ x108, x109 := bits.add_u64(x107, x104, u64(0x0))
+ x110, x111 := bits.add_u64(x105, x102, u64(fiat.u1(x109)))
+ x112, x113 := bits.add_u64(x103, x100, u64(fiat.u1(x111)))
+ x114 := (u64(fiat.u1(x113)) + x101)
+ x115, x116 := bits.add_u64(x91, x106, u64(0x0))
+ x117, x118 := bits.add_u64(x93, x108, u64(fiat.u1(x116)))
+ x119, x120 := bits.add_u64(x95, x110, u64(fiat.u1(x118)))
+ x121, x122 := bits.add_u64(x97, x112, u64(fiat.u1(x120)))
+ x123, x124 := bits.add_u64(x99, x114, u64(fiat.u1(x122)))
+ _, x125 := bits.mul_u64(x115, 0xccd1c8aaee00bc4f)
+ x128, x127 := bits.mul_u64(x125, 0xffffffff00000000)
+ x130, x129 := bits.mul_u64(x125, 0xffffffffffffffff)
+ x132, x131 := bits.mul_u64(x125, 0xbce6faada7179e84)
+ x134, x133 := bits.mul_u64(x125, 0xf3b9cac2fc632551)
+ x135, x136 := bits.add_u64(x134, x131, u64(0x0))
+ x137, x138 := bits.add_u64(x132, x129, u64(fiat.u1(x136)))
+ x139, x140 := bits.add_u64(x130, x127, u64(fiat.u1(x138)))
+ x141 := (u64(fiat.u1(x140)) + x128)
+ _, x143 := bits.add_u64(x115, x133, u64(0x0))
+ x144, x145 := bits.add_u64(x117, x135, u64(fiat.u1(x143)))
+ x146, x147 := bits.add_u64(x119, x137, u64(fiat.u1(x145)))
+ x148, x149 := bits.add_u64(x121, x139, u64(fiat.u1(x147)))
+ x150, x151 := bits.add_u64(x123, x141, u64(fiat.u1(x149)))
+ x152 := (u64(fiat.u1(x151)) + u64(fiat.u1(x124)))
+ x154, x153 := bits.mul_u64(x3, arg1[3])
+ x156, x155 := bits.mul_u64(x3, arg1[2])
+ x158, x157 := bits.mul_u64(x3, arg1[1])
+ x160, x159 := bits.mul_u64(x3, arg1[0])
+ x161, x162 := bits.add_u64(x160, x157, u64(0x0))
+ x163, x164 := bits.add_u64(x158, x155, u64(fiat.u1(x162)))
+ x165, x166 := bits.add_u64(x156, x153, u64(fiat.u1(x164)))
+ x167 := (u64(fiat.u1(x166)) + x154)
+ x168, x169 := bits.add_u64(x144, x159, u64(0x0))
+ x170, x171 := bits.add_u64(x146, x161, u64(fiat.u1(x169)))
+ x172, x173 := bits.add_u64(x148, x163, u64(fiat.u1(x171)))
+ x174, x175 := bits.add_u64(x150, x165, u64(fiat.u1(x173)))
+ x176, x177 := bits.add_u64(x152, x167, u64(fiat.u1(x175)))
+ _, x178 := bits.mul_u64(x168, 0xccd1c8aaee00bc4f)
+ x181, x180 := bits.mul_u64(x178, 0xffffffff00000000)
+ x183, x182 := bits.mul_u64(x178, 0xffffffffffffffff)
+ x185, x184 := bits.mul_u64(x178, 0xbce6faada7179e84)
+ x187, x186 := bits.mul_u64(x178, 0xf3b9cac2fc632551)
+ x188, x189 := bits.add_u64(x187, x184, u64(0x0))
+ x190, x191 := bits.add_u64(x185, x182, u64(fiat.u1(x189)))
+ x192, x193 := bits.add_u64(x183, x180, u64(fiat.u1(x191)))
+ x194 := (u64(fiat.u1(x193)) + x181)
+ _, x196 := bits.add_u64(x168, x186, u64(0x0))
+ x197, x198 := bits.add_u64(x170, x188, u64(fiat.u1(x196)))
+ x199, x200 := bits.add_u64(x172, x190, u64(fiat.u1(x198)))
+ x201, x202 := bits.add_u64(x174, x192, u64(fiat.u1(x200)))
+ x203, x204 := bits.add_u64(x176, x194, u64(fiat.u1(x202)))
+ x205 := (u64(fiat.u1(x204)) + u64(fiat.u1(x177)))
+ x206, x207 := bits.sub_u64(x197, 0xf3b9cac2fc632551, u64(0x0))
+ x208, x209 := bits.sub_u64(x199, 0xbce6faada7179e84, u64(fiat.u1(x207)))
+ x210, x211 := bits.sub_u64(x201, 0xffffffffffffffff, u64(fiat.u1(x209)))
+ x212, x213 := bits.sub_u64(x203, 0xffffffff00000000, u64(fiat.u1(x211)))
+ _, x215 := bits.sub_u64(x205, u64(0x0), u64(fiat.u1(x213)))
+ x216 := fiat.cmovznz_u64(fiat.u1(x215), x206, x197)
+ x217 := fiat.cmovznz_u64(fiat.u1(x215), x208, x199)
+ x218 := fiat.cmovznz_u64(fiat.u1(x215), x210, x201)
+ x219 := fiat.cmovznz_u64(fiat.u1(x215), x212, x203)
+ out1[0] = x216
+ out1[1] = x217
+ out1[2] = x218
+ out1[3] = x219
+}
+
+fe_add :: proc "contextless" (out1, arg1, arg2: ^Montgomery_Domain_Field_Element) {
+ x1, x2 := bits.add_u64(arg1[0], arg2[0], u64(0x0))
+ x3, x4 := bits.add_u64(arg1[1], arg2[1], u64(fiat.u1(x2)))
+ x5, x6 := bits.add_u64(arg1[2], arg2[2], u64(fiat.u1(x4)))
+ x7, x8 := bits.add_u64(arg1[3], arg2[3], u64(fiat.u1(x6)))
+ x9, x10 := bits.sub_u64(x1, 0xf3b9cac2fc632551, u64(0x0))
+ x11, x12 := bits.sub_u64(x3, 0xbce6faada7179e84, u64(fiat.u1(x10)))
+ x13, x14 := bits.sub_u64(x5, 0xffffffffffffffff, u64(fiat.u1(x12)))
+ x15, x16 := bits.sub_u64(x7, 0xffffffff00000000, u64(fiat.u1(x14)))
+ _, x18 := bits.sub_u64(u64(fiat.u1(x8)), u64(0x0), u64(fiat.u1(x16)))
+ x19 := fiat.cmovznz_u64(fiat.u1(x18), x9, x1)
+ x20 := fiat.cmovznz_u64(fiat.u1(x18), x11, x3)
+ x21 := fiat.cmovznz_u64(fiat.u1(x18), x13, x5)
+ x22 := fiat.cmovznz_u64(fiat.u1(x18), x15, x7)
+ out1[0] = x19
+ out1[1] = x20
+ out1[2] = x21
+ out1[3] = x22
+}
+
+fe_sub :: proc "contextless" (out1, arg1, arg2: ^Montgomery_Domain_Field_Element) {
+ x1, x2 := bits.sub_u64(arg1[0], arg2[0], u64(0x0))
+ x3, x4 := bits.sub_u64(arg1[1], arg2[1], u64(fiat.u1(x2)))
+ x5, x6 := bits.sub_u64(arg1[2], arg2[2], u64(fiat.u1(x4)))
+ x7, x8 := bits.sub_u64(arg1[3], arg2[3], u64(fiat.u1(x6)))
+ x9 := fiat.cmovznz_u64(fiat.u1(x8), u64(0x0), 0xffffffffffffffff)
+ x10, x11 := bits.add_u64(x1, (x9 & 0xf3b9cac2fc632551), u64(0x0))
+ x12, x13 := bits.add_u64(x3, (x9 & 0xbce6faada7179e84), u64(fiat.u1(x11)))
+ x14, x15 := bits.add_u64(x5, x9, u64(fiat.u1(x13)))
+ x16, _ := bits.add_u64(x7, (x9 & 0xffffffff00000000), u64(fiat.u1(x15)))
+ out1[0] = x10
+ out1[1] = x12
+ out1[2] = x14
+ out1[3] = x16
+}
+
+fe_opp :: proc "contextless" (out1, arg1: ^Montgomery_Domain_Field_Element) {
+ x1, x2 := bits.sub_u64(u64(0x0), arg1[0], u64(0x0))
+ x3, x4 := bits.sub_u64(u64(0x0), arg1[1], u64(fiat.u1(x2)))
+ x5, x6 := bits.sub_u64(u64(0x0), arg1[2], u64(fiat.u1(x4)))
+ x7, x8 := bits.sub_u64(u64(0x0), arg1[3], u64(fiat.u1(x6)))
+ x9 := fiat.cmovznz_u64(fiat.u1(x8), u64(0x0), 0xffffffffffffffff)
+ x10, x11 := bits.add_u64(x1, (x9 & 0xf3b9cac2fc632551), u64(0x0))
+ x12, x13 := bits.add_u64(x3, (x9 & 0xbce6faada7179e84), u64(fiat.u1(x11)))
+ x14, x15 := bits.add_u64(x5, x9, u64(fiat.u1(x13)))
+ x16, _ := bits.add_u64(x7, (x9 & 0xffffffff00000000), u64(fiat.u1(x15)))
+ out1[0] = x10
+ out1[1] = x12
+ out1[2] = x14
+ out1[3] = x16
+}
+
+fe_one :: proc "contextless" (out1: ^Montgomery_Domain_Field_Element) {
+ out1[0] = 0xc46353d039cdaaf
+ out1[1] = 0x4319055258e8617b
+ out1[2] = u64(0x0)
+ out1[3] = 0xffffffff
+}
+
+fe_non_zero :: proc "contextless" (arg1: ^Montgomery_Domain_Field_Element) -> u64 {
+ return arg1[0] | (arg1[1] | (arg1[2] | arg1[3]))
+}
+
+@(optimization_mode = "none")
+fe_cond_assign :: #force_no_inline proc "contextless" (
+ out1, arg1: ^Montgomery_Domain_Field_Element,
+ arg2: int,
+) {
+ x1 := fiat.cmovznz_u64(fiat.u1(arg2), out1[0], arg1[0])
+ x2 := fiat.cmovznz_u64(fiat.u1(arg2), out1[1], arg1[1])
+ x3 := fiat.cmovznz_u64(fiat.u1(arg2), out1[2], arg1[2])
+ x4 := fiat.cmovznz_u64(fiat.u1(arg2), out1[3], arg1[3])
+ out1[0] = x1
+ out1[1] = x2
+ out1[2] = x3
+ out1[3] = x4
+}
+
+fe_from_montgomery :: proc "contextless" (
+ out1: ^Non_Montgomery_Domain_Field_Element,
+ arg1: ^Montgomery_Domain_Field_Element,
+) {
+ x1 := arg1[0]
+ _, x2 := bits.mul_u64(x1, 0xccd1c8aaee00bc4f)
+ x5, x4 := bits.mul_u64(x2, 0xffffffff00000000)
+ x7, x6 := bits.mul_u64(x2, 0xffffffffffffffff)
+ x9, x8 := bits.mul_u64(x2, 0xbce6faada7179e84)
+ x11, x10 := bits.mul_u64(x2, 0xf3b9cac2fc632551)
+ x12, x13 := bits.add_u64(x11, x8, u64(0x0))
+ x14, x15 := bits.add_u64(x9, x6, u64(fiat.u1(x13)))
+ x16, x17 := bits.add_u64(x7, x4, u64(fiat.u1(x15)))
+ _, x19 := bits.add_u64(x1, x10, u64(0x0))
+ x20, x21 := bits.add_u64(u64(0x0), x12, u64(fiat.u1(x19)))
+ x22, x23 := bits.add_u64(u64(0x0), x14, u64(fiat.u1(x21)))
+ x24, x25 := bits.add_u64(u64(0x0), x16, u64(fiat.u1(x23)))
+ x26, x27 := bits.add_u64(x20, arg1[1], u64(0x0))
+ x28, x29 := bits.add_u64(x22, u64(0x0), u64(fiat.u1(x27)))
+ x30, x31 := bits.add_u64(x24, u64(0x0), u64(fiat.u1(x29)))
+ _, x32 := bits.mul_u64(x26, 0xccd1c8aaee00bc4f)
+ x35, x34 := bits.mul_u64(x32, 0xffffffff00000000)
+ x37, x36 := bits.mul_u64(x32, 0xffffffffffffffff)
+ x39, x38 := bits.mul_u64(x32, 0xbce6faada7179e84)
+ x41, x40 := bits.mul_u64(x32, 0xf3b9cac2fc632551)
+ x42, x43 := bits.add_u64(x41, x38, u64(0x0))
+ x44, x45 := bits.add_u64(x39, x36, u64(fiat.u1(x43)))
+ x46, x47 := bits.add_u64(x37, x34, u64(fiat.u1(x45)))
+ _, x49 := bits.add_u64(x26, x40, u64(0x0))
+ x50, x51 := bits.add_u64(x28, x42, u64(fiat.u1(x49)))
+ x52, x53 := bits.add_u64(x30, x44, u64(fiat.u1(x51)))
+ x54, x55 := bits.add_u64((u64(fiat.u1(x31)) + (u64(fiat.u1(x25)) + (u64(fiat.u1(x17)) + x5))), x46, u64(fiat.u1(x53)))
+ x56, x57 := bits.add_u64(x50, arg1[2], u64(0x0))
+ x58, x59 := bits.add_u64(x52, u64(0x0), u64(fiat.u1(x57)))
+ x60, x61 := bits.add_u64(x54, u64(0x0), u64(fiat.u1(x59)))
+ _, x62 := bits.mul_u64(x56, 0xccd1c8aaee00bc4f)
+ x65, x64 := bits.mul_u64(x62, 0xffffffff00000000)
+ x67, x66 := bits.mul_u64(x62, 0xffffffffffffffff)
+ x69, x68 := bits.mul_u64(x62, 0xbce6faada7179e84)
+ x71, x70 := bits.mul_u64(x62, 0xf3b9cac2fc632551)
+ x72, x73 := bits.add_u64(x71, x68, u64(0x0))
+ x74, x75 := bits.add_u64(x69, x66, u64(fiat.u1(x73)))
+ x76, x77 := bits.add_u64(x67, x64, u64(fiat.u1(x75)))
+ _, x79 := bits.add_u64(x56, x70, u64(0x0))
+ x80, x81 := bits.add_u64(x58, x72, u64(fiat.u1(x79)))
+ x82, x83 := bits.add_u64(x60, x74, u64(fiat.u1(x81)))
+ x84, x85 := bits.add_u64((u64(fiat.u1(x61)) + (u64(fiat.u1(x55)) + (u64(fiat.u1(x47)) + x35))), x76, u64(fiat.u1(x83)))
+ x86, x87 := bits.add_u64(x80, arg1[3], u64(0x0))
+ x88, x89 := bits.add_u64(x82, u64(0x0), u64(fiat.u1(x87)))
+ x90, x91 := bits.add_u64(x84, u64(0x0), u64(fiat.u1(x89)))
+ _, x92 := bits.mul_u64(x86, 0xccd1c8aaee00bc4f)
+ x95, x94 := bits.mul_u64(x92, 0xffffffff00000000)
+ x97, x96 := bits.mul_u64(x92, 0xffffffffffffffff)
+ x99, x98 := bits.mul_u64(x92, 0xbce6faada7179e84)
+ x101, x100 := bits.mul_u64(x92, 0xf3b9cac2fc632551)
+ x102, x103 := bits.add_u64(x101, x98, u64(0x0))
+ x104, x105 := bits.add_u64(x99, x96, u64(fiat.u1(x103)))
+ x106, x107 := bits.add_u64(x97, x94, u64(fiat.u1(x105)))
+ _, x109 := bits.add_u64(x86, x100, u64(0x0))
+ x110, x111 := bits.add_u64(x88, x102, u64(fiat.u1(x109)))
+ x112, x113 := bits.add_u64(x90, x104, u64(fiat.u1(x111)))
+ x114, x115 := bits.add_u64((u64(fiat.u1(x91)) + (u64(fiat.u1(x85)) + (u64(fiat.u1(x77)) + x65))), x106, u64(fiat.u1(x113)))
+ x116 := (u64(fiat.u1(x115)) + (u64(fiat.u1(x107)) + x95))
+ x117, x118 := bits.sub_u64(x110, 0xf3b9cac2fc632551, u64(0x0))
+ x119, x120 := bits.sub_u64(x112, 0xbce6faada7179e84, u64(fiat.u1(x118)))
+ x121, x122 := bits.sub_u64(x114, 0xffffffffffffffff, u64(fiat.u1(x120)))
+ x123, x124 := bits.sub_u64(x116, 0xffffffff00000000, u64(fiat.u1(x122)))
+ _, x126 := bits.sub_u64(u64(0x0), u64(0x0), u64(fiat.u1(x124)))
+ x127 := fiat.cmovznz_u64(fiat.u1(x126), x117, x110)
+ x128 := fiat.cmovznz_u64(fiat.u1(x126), x119, x112)
+ x129 := fiat.cmovznz_u64(fiat.u1(x126), x121, x114)
+ x130 := fiat.cmovznz_u64(fiat.u1(x126), x123, x116)
+ out1[0] = x127
+ out1[1] = x128
+ out1[2] = x129
+ out1[3] = x130
+}
+
+fe_to_montgomery :: proc "contextless" (
+ out1: ^Montgomery_Domain_Field_Element,
+ arg1: ^Non_Montgomery_Domain_Field_Element,
+) {
+ x1 := arg1[1]
+ x2 := arg1[2]
+ x3 := arg1[3]
+ x4 := arg1[0]
+ x6, x5 := bits.mul_u64(x4, 0x66e12d94f3d95620)
+ x8, x7 := bits.mul_u64(x4, 0x2845b2392b6bec59)
+ x10, x9 := bits.mul_u64(x4, 0x4699799c49bd6fa6)
+ x12, x11 := bits.mul_u64(x4, 0x83244c95be79eea2)
+ x13, x14 := bits.add_u64(x12, x9, u64(0x0))
+ x15, x16 := bits.add_u64(x10, x7, u64(fiat.u1(x14)))
+ x17, x18 := bits.add_u64(x8, x5, u64(fiat.u1(x16)))
+ _, x19 := bits.mul_u64(x11, 0xccd1c8aaee00bc4f)
+ x22, x21 := bits.mul_u64(x19, 0xffffffff00000000)
+ x24, x23 := bits.mul_u64(x19, 0xffffffffffffffff)
+ x26, x25 := bits.mul_u64(x19, 0xbce6faada7179e84)
+ x28, x27 := bits.mul_u64(x19, 0xf3b9cac2fc632551)
+ x29, x30 := bits.add_u64(x28, x25, u64(0x0))
+ x31, x32 := bits.add_u64(x26, x23, u64(fiat.u1(x30)))
+ x33, x34 := bits.add_u64(x24, x21, u64(fiat.u1(x32)))
+ _, x36 := bits.add_u64(x11, x27, u64(0x0))
+ x37, x38 := bits.add_u64(x13, x29, u64(fiat.u1(x36)))
+ x39, x40 := bits.add_u64(x15, x31, u64(fiat.u1(x38)))
+ x41, x42 := bits.add_u64(x17, x33, u64(fiat.u1(x40)))
+ x43, x44 := bits.add_u64((u64(fiat.u1(x18)) + x6), (u64(fiat.u1(x34)) + x22), u64(fiat.u1(x42)))
+ x46, x45 := bits.mul_u64(x1, 0x66e12d94f3d95620)
+ x48, x47 := bits.mul_u64(x1, 0x2845b2392b6bec59)
+ x50, x49 := bits.mul_u64(x1, 0x4699799c49bd6fa6)
+ x52, x51 := bits.mul_u64(x1, 0x83244c95be79eea2)
+ x53, x54 := bits.add_u64(x52, x49, u64(0x0))
+ x55, x56 := bits.add_u64(x50, x47, u64(fiat.u1(x54)))
+ x57, x58 := bits.add_u64(x48, x45, u64(fiat.u1(x56)))
+ x59, x60 := bits.add_u64(x37, x51, u64(0x0))
+ x61, x62 := bits.add_u64(x39, x53, u64(fiat.u1(x60)))
+ x63, x64 := bits.add_u64(x41, x55, u64(fiat.u1(x62)))
+ x65, x66 := bits.add_u64(x43, x57, u64(fiat.u1(x64)))
+ _, x67 := bits.mul_u64(x59, 0xccd1c8aaee00bc4f)
+ x70, x69 := bits.mul_u64(x67, 0xffffffff00000000)
+ x72, x71 := bits.mul_u64(x67, 0xffffffffffffffff)
+ x74, x73 := bits.mul_u64(x67, 0xbce6faada7179e84)
+ x76, x75 := bits.mul_u64(x67, 0xf3b9cac2fc632551)
+ x77, x78 := bits.add_u64(x76, x73, u64(0x0))
+ x79, x80 := bits.add_u64(x74, x71, u64(fiat.u1(x78)))
+ x81, x82 := bits.add_u64(x72, x69, u64(fiat.u1(x80)))
+ _, x84 := bits.add_u64(x59, x75, u64(0x0))
+ x85, x86 := bits.add_u64(x61, x77, u64(fiat.u1(x84)))
+ x87, x88 := bits.add_u64(x63, x79, u64(fiat.u1(x86)))
+ x89, x90 := bits.add_u64(x65, x81, u64(fiat.u1(x88)))
+ x91, x92 := bits.add_u64(((u64(fiat.u1(x66)) + u64(fiat.u1(x44))) + (u64(fiat.u1(x58)) + x46)), (u64(fiat.u1(x82)) + x70), u64(fiat.u1(x90)))
+ x94, x93 := bits.mul_u64(x2, 0x66e12d94f3d95620)
+ x96, x95 := bits.mul_u64(x2, 0x2845b2392b6bec59)
+ x98, x97 := bits.mul_u64(x2, 0x4699799c49bd6fa6)
+ x100, x99 := bits.mul_u64(x2, 0x83244c95be79eea2)
+ x101, x102 := bits.add_u64(x100, x97, u64(0x0))
+ x103, x104 := bits.add_u64(x98, x95, u64(fiat.u1(x102)))
+ x105, x106 := bits.add_u64(x96, x93, u64(fiat.u1(x104)))
+ x107, x108 := bits.add_u64(x85, x99, u64(0x0))
+ x109, x110 := bits.add_u64(x87, x101, u64(fiat.u1(x108)))
+ x111, x112 := bits.add_u64(x89, x103, u64(fiat.u1(x110)))
+ x113, x114 := bits.add_u64(x91, x105, u64(fiat.u1(x112)))
+ _, x115 := bits.mul_u64(x107, 0xccd1c8aaee00bc4f)
+ x118, x117 := bits.mul_u64(x115, 0xffffffff00000000)
+ x120, x119 := bits.mul_u64(x115, 0xffffffffffffffff)
+ x122, x121 := bits.mul_u64(x115, 0xbce6faada7179e84)
+ x124, x123 := bits.mul_u64(x115, 0xf3b9cac2fc632551)
+ x125, x126 := bits.add_u64(x124, x121, u64(0x0))
+ x127, x128 := bits.add_u64(x122, x119, u64(fiat.u1(x126)))
+ x129, x130 := bits.add_u64(x120, x117, u64(fiat.u1(x128)))
+ _, x132 := bits.add_u64(x107, x123, u64(0x0))
+ x133, x134 := bits.add_u64(x109, x125, u64(fiat.u1(x132)))
+ x135, x136 := bits.add_u64(x111, x127, u64(fiat.u1(x134)))
+ x137, x138 := bits.add_u64(x113, x129, u64(fiat.u1(x136)))
+ x139, x140 := bits.add_u64(((u64(fiat.u1(x114)) + u64(fiat.u1(x92))) + (u64(fiat.u1(x106)) + x94)), (u64(fiat.u1(x130)) + x118), u64(fiat.u1(x138)))
+ x142, x141 := bits.mul_u64(x3, 0x66e12d94f3d95620)
+ x144, x143 := bits.mul_u64(x3, 0x2845b2392b6bec59)
+ x146, x145 := bits.mul_u64(x3, 0x4699799c49bd6fa6)
+ x148, x147 := bits.mul_u64(x3, 0x83244c95be79eea2)
+ x149, x150 := bits.add_u64(x148, x145, u64(0x0))
+ x151, x152 := bits.add_u64(x146, x143, u64(fiat.u1(x150)))
+ x153, x154 := bits.add_u64(x144, x141, u64(fiat.u1(x152)))
+ x155, x156 := bits.add_u64(x133, x147, u64(0x0))
+ x157, x158 := bits.add_u64(x135, x149, u64(fiat.u1(x156)))
+ x159, x160 := bits.add_u64(x137, x151, u64(fiat.u1(x158)))
+ x161, x162 := bits.add_u64(x139, x153, u64(fiat.u1(x160)))
+ _, x163 := bits.mul_u64(x155, 0xccd1c8aaee00bc4f)
+ x166, x165 := bits.mul_u64(x163, 0xffffffff00000000)
+ x168, x167 := bits.mul_u64(x163, 0xffffffffffffffff)
+ x170, x169 := bits.mul_u64(x163, 0xbce6faada7179e84)
+ x172, x171 := bits.mul_u64(x163, 0xf3b9cac2fc632551)
+ x173, x174 := bits.add_u64(x172, x169, u64(0x0))
+ x175, x176 := bits.add_u64(x170, x167, u64(fiat.u1(x174)))
+ x177, x178 := bits.add_u64(x168, x165, u64(fiat.u1(x176)))
+ _, x180 := bits.add_u64(x155, x171, u64(0x0))
+ x181, x182 := bits.add_u64(x157, x173, u64(fiat.u1(x180)))
+ x183, x184 := bits.add_u64(x159, x175, u64(fiat.u1(x182)))
+ x185, x186 := bits.add_u64(x161, x177, u64(fiat.u1(x184)))
+ x187, x188 := bits.add_u64(((u64(fiat.u1(x162)) + u64(fiat.u1(x140))) + (u64(fiat.u1(x154)) + x142)), (u64(fiat.u1(x178)) + x166), u64(fiat.u1(x186)))
+ x189, x190 := bits.sub_u64(x181, 0xf3b9cac2fc632551, u64(0x0))
+ x191, x192 := bits.sub_u64(x183, 0xbce6faada7179e84, u64(fiat.u1(x190)))
+ x193, x194 := bits.sub_u64(x185, 0xffffffffffffffff, u64(fiat.u1(x192)))
+ x195, x196 := bits.sub_u64(x187, 0xffffffff00000000, u64(fiat.u1(x194)))
+ _, x198 := bits.sub_u64(u64(fiat.u1(x188)), u64(0x0), u64(fiat.u1(x196)))
+ x199 := fiat.cmovznz_u64(fiat.u1(x198), x189, x181)
+ x200 := fiat.cmovznz_u64(fiat.u1(x198), x191, x183)
+ x201 := fiat.cmovznz_u64(fiat.u1(x198), x193, x185)
+ x202 := fiat.cmovznz_u64(fiat.u1(x198), x195, x187)
+ out1[0] = x199
+ out1[1] = x200
+ out1[2] = x201
+ out1[3] = x202
+}
diff --git a/core/crypto/_subtle/subtle.odin b/core/crypto/_subtle/subtle.odin
new file mode 100644
index 000000000..89328072c
--- /dev/null
+++ b/core/crypto/_subtle/subtle.odin
@@ -0,0 +1,42 @@
+/*
+Various useful bit operations in constant time.
+*/
+package _subtle
+
+import "core:math/bits"
+
+// byte_eq returns 1 iff a == b, 0 otherwise.
+@(optimization_mode="none")
+byte_eq :: proc "contextless" (a, b: byte) -> int {
+ v := a ~ b
+
+ // v == 0 iff a == b. The subtraction will underflow, setting the
+ // sign bit, which will get returned.
+ return int((u32(v)-1) >> 31)
+}
+
+// u64_eq returns 1 iff a == b, 0 otherwise.
+@(optimization_mode="none")
+u64_eq :: proc "contextless" (a, b: u64) -> u64 {
+ _, borrow := bits.sub_u64(0, a ~ b, 0)
+ return (~borrow) & 1
+}
+
+eq :: proc {
+ byte_eq,
+ u64_eq,
+}
+
+// u64_is_zero returns 1 iff a == 0, 0 otherwise.
+@(optimization_mode="none")
+u64_is_zero :: proc "contextless" (a: u64) -> u64 {
+ _, borrow := bits.sub_u64(a, 1, 0)
+ return borrow
+}
+
+// u64_is_non_zero returns 1 iff a != 0, 0 otherwise.
+@(optimization_mode="none")
+u64_is_non_zero :: proc "contextless" (a: u64) -> u64 {
+ is_zero := u64_is_zero(a)
+ return (~is_zero) & 1
+}
diff --git a/core/crypto/_weierstrass/fe.odin b/core/crypto/_weierstrass/fe.odin
new file mode 100644
index 000000000..1a160a03c
--- /dev/null
+++ b/core/crypto/_weierstrass/fe.odin
@@ -0,0 +1,135 @@
+package _weierstrass
+
+import p256r1 "core:crypto/_fiat/field_p256r1"
+import "core:math/bits"
+
+Field_Element_p256r1 :: p256r1.Montgomery_Domain_Field_Element
+
+FE_SIZE_P256R1 :: 32
+
+fe_clear :: proc {
+ p256r1.fe_clear,
+}
+
+fe_clear_vec :: proc {
+ p256r1.fe_clear_vec,
+}
+
+fe_set_bytes :: proc {
+ p256r1.fe_from_bytes,
+}
+fe_bytes :: proc {
+ p256r1.fe_to_bytes,
+}
+
+fe_set :: proc {
+ p256r1.fe_set,
+}
+
+fe_zero :: proc {
+ p256r1.fe_zero,
+}
+
+fe_a :: proc {
+ fe_a_p256r1,
+}
+
+fe_b :: proc {
+ fe_b_p256r1,
+}
+
+fe_gen_x :: proc {
+ fe_gen_x_p256r1,
+}
+
+fe_gen_y :: proc {
+ fe_gen_y_p256r1,
+}
+
+fe_one :: proc {
+ p256r1.fe_one,
+}
+
+fe_add :: proc {
+ p256r1.fe_add,
+}
+
+fe_sub :: proc {
+ p256r1.fe_sub,
+}
+
+fe_negate :: proc {
+ p256r1.fe_opp,
+}
+
+fe_mul :: proc {
+ p256r1.fe_mul,
+}
+
+fe_square :: proc {
+ p256r1.fe_square,
+}
+
+fe_inv :: proc {
+ p256r1.fe_inv,
+}
+
+fe_sqrt :: proc {
+ p256r1.fe_sqrt,
+}
+
+fe_equal :: proc {
+ p256r1.fe_equal,
+}
+
+fe_is_odd :: proc {
+ p256r1.fe_is_odd,
+}
+
+fe_is_zero :: proc {
+ fe_is_zero_p256r1,
+}
+
+fe_cond_select :: proc {
+ p256r1.fe_cond_select,
+}
+
+fe_a_p256r1 :: proc "contextless" (fe: ^Field_Element_p256r1) {
+ // a = 0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc
+ // = -3 mod p
+ fe[0] = 18446744073709551612
+ fe[1] = 17179869183
+ fe[2] = 0
+ fe[3] = 18446744056529682436
+}
+
+fe_b_p256r1 :: proc "contextless" (fe: ^Field_Element_p256r1) {
+ // b = 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b
+ fe[0] = 15608596021259845087
+ fe[1] = 12461466548982526096
+ fe[2] = 16546823903870267094
+ fe[3] = 15866188208926050356
+}
+
+fe_gen_x_p256r1 :: proc "contextless" (fe: ^Field_Element_p256r1) {
+ // G_x = 0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296
+ fe[0] = 8784043285714375740
+ fe[1] = 8483257759279461889
+ fe[2] = 8789745728267363600
+ fe[3] = 1770019616739251654
+}
+
+fe_gen_y_p256r1 :: proc "contextless" (fe: ^Field_Element_p256r1) {
+ // G_y = 0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5
+ fe[0] = 15992936863339206154
+ fe[1] = 10037038012062884956
+ fe[2] = 15197544864945402661
+ fe[3] = 9615747158586711429
+}
+
+@(require_results)
+fe_is_zero_p256r1 :: proc "contextless" (fe: ^Field_Element_p256r1) -> int {
+ ctrl := p256r1.fe_non_zero(fe)
+ _, borrow := bits.sub_u64(ctrl, 1, 0)
+ return int(borrow)
+}
diff --git a/core/crypto/_weierstrass/point.odin b/core/crypto/_weierstrass/point.odin
new file mode 100644
index 000000000..cde82ebb2
--- /dev/null
+++ b/core/crypto/_weierstrass/point.odin
@@ -0,0 +1,548 @@
+package _weierstrass
+
+/*
+This implements prime order short Weierstrass curves defined over a field
+k with char(k) != 2, 3 (`y^2 = x^3 + ax + b`). for the purpose of
+implementing ECDH and ECDSA. Use of this package for other purposes is
+NOT RECOMMENDED.
+
+As an explicit simplicity/performance tradeoff, projective representation
+was chosen so that it is possible to use the complete addition
+formulas.
+
+See:
+- https://eprint.iacr.org/2015/1060.pdf
+- https://hyperelliptic.org/EFD/g1p/auto-shortw-projective.html
+
+WARNING: The point addition and doubling formulas are specialized for
+`a = -3`, which covers secp256r1, secp384r1, secp521r1, FRP256v1, SM2,
+and GOST 34.10. The brainpool curves and secp256k1 are NOT SUPPORTED
+and would require slightly different formulas.
+*/
+
+Point_p256r1 :: struct {
+ x: Field_Element_p256r1,
+ y: Field_Element_p256r1,
+ z: Field_Element_p256r1,
+}
+
+@(require_results)
+pt_set_xy_bytes :: proc "contextless" (p: ^$T, x_raw, y_raw: []byte) -> bool {
+ when T == Point_p256r1 {
+ FE_SZ :: FE_SIZE_P256R1
+ x, y: Field_Element_p256r1
+ defer fe_clear_vec([]^Field_Element_p256r1{&x, &y})
+ } else {
+ #panic("weierstrass: invalid curve")
+ }
+
+ if len(x_raw) != FE_SZ || len(y_raw) != FE_SZ {
+ return false
+ }
+
+ if !fe_set_bytes(&x, x_raw) {
+ return false
+ }
+ if !fe_set_bytes(&y, y_raw) {
+ return false
+ }
+ if !is_on_curve(&x, &y) {
+ return false
+ }
+
+ fe_set(&p.x, &x)
+ fe_set(&p.y, &y)
+ fe_one(&p.z)
+
+ return true
+}
+
+@(require_results)
+pt_set_x_bytes :: proc "contextless" (p: ^$T, x_raw: []byte, y_is_odd: int) -> bool {
+ when T == Point_p256r1 {
+ FE_SZ :: FE_SIZE_P256R1
+ x, y, yy, y_neg: Field_Element_p256r1
+ defer fe_clear_vec([]^Field_Element_p256r1{&x, &y, &yy, &y_neg})
+ } else {
+ #panic("weierstrass: invalid curve")
+ }
+
+ if len(x_raw) != FE_SZ {
+ return false
+ }
+
+ if !fe_set_bytes(&x, x_raw) {
+ return false
+ }
+ set_yy_candidate(&yy, &x)
+ if fe_sqrt(&y, &yy) != 1 {
+ return false
+ }
+
+ // Pick the correct y-coordinate.
+ fe_negate(&y_neg, &y)
+ parity_neq := (y_is_odd ~ fe_is_odd(&y)) & 1
+
+ fe_set(&p.x, &x)
+ fe_cond_select(&p.y, &y, &y_neg, parity_neq)
+ fe_one(&p.z)
+
+ return true
+}
+
+@(require_results)
+pt_bytes :: proc "contextless" (x, y: []byte, p: ^$T) -> bool {
+ when T == Point_p256r1 {
+ FE_SZ :: FE_SIZE_P256R1
+ } else {
+ #panic("weierstrass: invalid curve")
+ }
+
+ if pt_is_identity(p) == 1 {
+ return false
+ }
+
+ // Convert to affine coordinates.
+ pt_rescale(p, p)
+
+ switch len(x) {
+ case 0:
+ case FE_SZ:
+ fe_bytes(x, &p.x)
+ case:
+ panic_contextless("weierstrass: invalid x buffer")
+ }
+ switch len(y) {
+ case 0:
+ case FE_SZ:
+ fe_bytes(y, &p.y)
+ case:
+ panic_contextless("weierstrass: invalid y buffer")
+ }
+
+ return true
+}
+
+pt_set :: proc "contextless" (p, q: ^$T) {
+ fe_set(&p.x, &q.x)
+ fe_set(&p.y, &q.y)
+ fe_set(&p.z, &q.z)
+}
+
+pt_identity :: proc "contextless" (p: ^$T) {
+ fe_zero(&p.x)
+ fe_one(&p.y)
+ fe_zero(&p.z)
+}
+
+pt_generator :: proc "contextless" (p: ^$T) {
+ fe_gen_x(&p.x)
+ fe_gen_y(&p.y)
+ fe_one(&p.z)
+}
+
+pt_clear :: proc "contextless" (p: ^$T) {
+ fe_clear(&p.x)
+ fe_clear(&p.y)
+ fe_clear(&p.z)
+}
+
+pt_clear_vec :: proc "contextless" (arg: []^$T) {
+ for p in arg {
+ pt_clear(p)
+ }
+}
+
+pt_add :: proc "contextless" (p, a, b: ^$T) {
+ // Algorithm 4 from "Complete addition formulas for prime
+ // order elliptic curves" by Renes, Costello, and Batina.
+ //
+ // The formula is complete in that it is valid for all a and b,
+ // without exceptions or extra assumptions about the inputs.
+ //
+ // The operation costs are `12M + 2mb + 29a`.
+
+ when T == Point_p256r1 {
+ t0, t1, t2, t3, t4, b_fe: Field_Element_p256r1
+ x3, y3, z3: Field_Element_p256r1
+ defer fe_clear_vec([]^Field_Element_p256r1{&t0, &t1, &t2, &t3, &t4, &x3, &y3, &z3})
+ } else {
+ #panic("weierstrass: invalid curve")
+ }
+
+ x1, y1, z1 := &a.x, &a.y, &a.z
+ x2, y2, z2 := &b.x, &b.y, &b.z
+
+ fe_b(&b_fe)
+
+ // t0 := X1 * X2 ; t1 := Y1 * Y2 ; t2 := Z1 * Z2 ;
+ fe_mul(&t0, x1, x2)
+ fe_mul(&t1, y1, y2)
+ fe_mul(&t2, z1, z2)
+
+ // t3 := X1 + Y1 ; t4 := X2 + Y2 ; t3 := t3 * t4 ;
+ fe_add(&t3, x1, y1)
+ fe_add(&t4, x2, y2)
+ fe_mul(&t3, &t3, &t4)
+
+ // t4 := t0 + t1 ; t3 := t3 - t4 ; t4 := Y1 + Z1 ;
+ fe_add(&t4, &t0, &t1)
+ fe_sub(&t3, &t3, &t4)
+ fe_add(&t4, y1, z1)
+
+ // X3 := Y2 + Z2 ; t4 := t4 * X3 ; X3 := t1 + t2 ;
+ fe_add(&x3, y2, z2)
+ fe_mul(&t4, &t4, &x3)
+ fe_add(&x3, &t1, &t2)
+
+ // t4 := t4 - X3 ; X3 := X1 + Z1 ; Y3 := X2 + Z2 ;
+ fe_sub(&t4, &t4, &x3)
+ fe_add(&x3, x1, z1)
+ fe_add(&y3, x2, z2)
+
+ // X3 := X3 * Y3 ; Y3 := t0 + t2 ; Y3 := X3 - Y3 ;
+ fe_mul(&x3, &x3, &y3)
+ fe_add(&y3, &t0, &t2)
+ fe_sub(&y3, &x3, &y3)
+
+ // Z3 := b * t2 ; X3 := Y3 - Z3 ; Z3 := X3 + X3 ;
+ fe_mul(&z3, &b_fe, &t2)
+ fe_sub(&x3, &y3, &z3)
+ fe_add(&z3, &x3, &x3)
+
+ // X3 := X3 + Z3 ; Z3 := t1 - X3 ; X3 := t1 + X3 ;
+ fe_add(&x3, &x3, &z3)
+ fe_sub(&z3, &t1, &x3)
+ fe_add(&x3, &t1, &x3)
+
+ // Y3 := b * Y3 ; t1 := t2 + t2 ; t2 := t1 + t2 ;
+ fe_mul(&y3, &b_fe, &y3)
+ fe_add(&t1, &t2, &t2)
+ fe_add(&t2, &t1, &t2)
+
+ // Y3 := Y3 - t2 ; Y3 := Y3 - t0 ; t1 := Y3 + Y3 ;
+ fe_sub(&y3, &y3, &t2)
+ fe_sub(&y3, &y3, &t0)
+ fe_add(&t1, &y3, &y3)
+
+ // Y3 := t1 + Y3 ; t1 := t0 + t0 ; t0 := t1 + t0 ;
+ fe_add(&y3, &t1, &y3)
+ fe_add(&t1, &t0, &t0)
+ fe_add(&t0, &t1, &t0)
+
+ // t0 := t0 - t2 ; t1 := t4 * Y3 ; t2 := t0 * Y3 ;
+ fe_sub(&t0, &t0, &t2)
+ fe_mul(&t1, &t4, &y3)
+ fe_mul(&t2, &t0, &y3)
+
+ // Y3 := X3 * Z3 ; Y3 := Y3 + t2 ; X3 := t3 * X3 ;
+ fe_mul(&y3, &x3, &z3)
+ fe_add(&y3, &y3, &t2)
+ fe_mul(&x3, &t3, &x3)
+
+ // X3 := X3 - t1 ; Z3 := t4 * Z3 ; t1 := t3 * t0 ;
+ fe_sub(&x3, &x3, &t1)
+ fe_mul(&z3, &t4, &z3)
+ fe_mul(&t1, &t3, &t0)
+
+ // Z3 := Z3 + t1 ;
+ fe_add(&z3, &z3, &t1)
+
+ // return X3 , Y3 , Z3 ;
+ fe_set(&p.x, &x3)
+ fe_set(&p.y, &y3)
+ fe_set(&p.z, &z3)
+}
+
+@(private)
+pt_add_mixed :: proc "contextless" (p, a: ^$T, x2, y2: ^$U) {
+ // Algorithm 5 from "Complete addition formulas for prime
+ // order elliptic curves" by Renes, Costello, and Batina.
+ //
+ // The formula is mixed in that it assumes the z-coordinate
+ // of the addend (`Z2`) is `1`, meaning that it CAN NOT
+ // handle the addend being the point at infinity.
+ //
+ // The operation costs are `11M + 2mb + 23a` saving
+ // `1M + 6a` over `pt_add`.
+
+ when T == Point_p256r1 && U == Field_Element_p256r1 {
+ t0, t1, t2, t3, t4, b_fe: Field_Element_p256r1
+ x3, y3, z3: Field_Element_p256r1
+ defer fe_clear_vec([]^Field_Element_p256r1{&t0, &t1, &t2, &t3, &t4, &x3, &y3, &z3})
+ } else {
+ #panic("weierstrass: invalid curve")
+ }
+
+ x1, y1, z1 := &a.x, &a.y, &a.z
+
+ fe_b(&b_fe)
+
+ // t0 := X1 * X2 ; t1 := Y1 * Y2 ; t3 := X2 + Y2 ;
+ fe_mul(&t0, x1, x2)
+ fe_mul(&t1, y1, y2)
+ fe_add(&t3, x2, y2)
+
+ // t4 := X1 + Y1 ; t3 := t3 * t4 ; t4 := t0 + t1 ;
+ fe_add(&t4, x1, y1)
+ fe_mul(&t3, &t3, &t4)
+ fe_add(&t4, &t0, &t1)
+
+ // t3 := t3 − t4 ; t4 := Y2 * Z1 ; t4 := t4 + Y1 ;
+ fe_sub(&t3, &t3, &t4)
+ fe_mul(&t4, y2, z1)
+ fe_add(&t4, &t4, y1)
+
+ // Y3 := X2 * Z1 ; Y3 := Y3 + X1 ; Z3 := b * Z1 ;
+ fe_mul(&y3, x2, z1)
+ fe_add(&y3, &y3, x1)
+ fe_mul(&z3, &b_fe, z1)
+
+ // X3 := Y3 − Z3 ; Z3 := X3 + X3 ; X3 := X3 + Z3 ;
+ fe_sub(&x3, &y3, &z3)
+ fe_add(&z3, &x3, &x3)
+ fe_add(&x3, &x3, &z3)
+
+ // Z3 := t1 − X3 ; X3 := t1 + X3 ;. Y3 := b * Y3 ;
+ fe_sub(&z3, &t1, &x3)
+ fe_add(&x3, &t1, &x3)
+ fe_mul(&y3, &b_fe, &y3)
+
+ // t1 := Z1 + Z1 ; t2 := t1 + Z1 ; Y3 := Y3 − t2 ;
+ fe_add(&t1, z1, z1)
+ fe_add(&t2, &t1, z1)
+ fe_sub(&y3, &y3, &t2)
+
+ // Y3 := Y3 − t0 ; t1 := Y3 + Y3 ; Y3 := t1 + Y3 ;
+ fe_sub(&y3, &y3, &t0)
+ fe_add(&t1, &y3, &y3)
+ fe_add(&y3, &t1, &y3)
+
+ // t1 := t0 + t0 ; t0 := t1 + t0 ; t0 := t0 − t2 ;
+ fe_add(&t1, &t0, &t0)
+ fe_add(&t0, &t1, &t0)
+ fe_sub(&t0, &t0, &t2)
+
+ // t1 := t4 * Y3 ; t2 := t0 * Y3 ; Y3 := X3 * Z3 ;
+ fe_mul(&t1, &t4, &y3)
+ fe_mul(&t2, &t0, &y3)
+ fe_mul(&y3, &x3, &z3)
+
+ // Y3 := Y3 + t2 ; X3 := t3 * X3 ; X3 := X3 − t1 ;
+ fe_add(&y3, &y3, &t2)
+ fe_mul(&x3, &t3, &x3)
+ fe_sub(&x3, &x3, &t1)
+
+ // Z3 := t4 * Z3 ; t1 := t3 * t0 ; Z3 := Z3 + t1 ;
+ fe_mul(&z3, &t4, &z3)
+ fe_mul(&t1, &t3, &t0)
+ fe_add(&z3, &z3, &t1)
+
+ // return X3 , Y3 , Z3 ;
+ fe_set(&p.x, &x3)
+ fe_set(&p.y, &y3)
+ fe_set(&p.z, &z3)
+}
+
+pt_double :: proc "contextless" (p, a: ^$T) {
+ // Algorithm 6 from "Complete addition formulas for prime
+ // order elliptic curves" by Renes, Costello, and Batina.
+ //
+ // The formula is complete in that it is valid for all a,
+ // without exceptions or extra assumptions about the inputs.
+ //
+ // The operation costs are `8M + 3S + 2mb + 21a`.
+
+ when T == Point_p256r1 {
+ t0, t1, t2, t3, b_fe: Field_Element_p256r1
+ x3, y3, z3: Field_Element_p256r1
+ defer fe_clear_vec([]^Field_Element_p256r1{&t0, &t1, &t2, &t3, &x3, &y3, &z3})
+ } else {
+ #panic("weierstrass: invalid curve")
+ }
+
+ x, y, z := &a.x, &a.y, &a.z
+
+ fe_b(&b_fe)
+
+ // t0 := X ^2; t1 := Y ^2; t2 := Z ^2;
+ fe_square(&t0, x)
+ fe_square(&t1, y)
+ fe_square(&t2, z)
+
+ // t3 := X * Y ; t3 := t3 + t3 ; Z3 := X * Z ;
+ fe_mul(&t3, x, y)
+ fe_add(&t3, &t3, &t3)
+ fe_mul(&z3, x, z)
+
+ // Z3 := Z3 + Z3 ; Y3 := b * t2 ; Y3 := Y3 - Z3 ;
+ fe_add(&z3, &z3, &z3)
+ fe_mul(&y3, &b_fe, &t2)
+ fe_sub(&y3, &y3, &z3)
+
+ // X3 := Y3 + Y3 ; Y3 := X3 + Y3 ; X3 := t1 - Y3 ;
+ fe_add(&x3, &y3, &y3)
+ fe_add(&y3, &x3, &y3)
+ fe_sub(&x3, &t1, &y3)
+
+ // Y3 := t1 + Y3 ; Y3 := X3 * Y3 ; X3 := X3 * t3 ;
+ fe_add(&y3, &t1, &y3)
+ fe_mul(&y3, &x3, &y3)
+ fe_mul(&x3, &x3, &t3)
+
+ // t3 := t2 + t2 ; t2 := t2 + t3 ; Z3 := b * Z3 ;
+ fe_add(&t3, &t2, &t2)
+ fe_add(&t2, &t2, &t3)
+ fe_mul(&z3, &b_fe, &z3)
+
+ // Z3 := Z3 - t2 ; Z3 := Z3 - t0 ; t3 := Z3 + Z3 ;
+ fe_sub(&z3, &z3, &t2)
+ fe_sub(&z3, &z3, &t0)
+ fe_add(&t3, &z3, &z3)
+
+ // Z3 := Z3 + t3 ; t3 := t0 + t0 ; t0 := t3 + t0 ;
+ fe_add(&z3, &z3, &t3)
+ fe_add(&t3, &t0, &t0)
+ fe_add(&t0, &t3, &t0)
+
+ // t0 := t0 - t2 ; t0 := t0 * Z3 ; Y3 := Y3 + t0 ;
+ fe_sub(&t0, &t0, &t2)
+ fe_mul(&t0, &t0, &z3)
+ fe_add(&y3, &y3, &t0)
+
+ // t0 := Y * Z ; t0 := t0 + t0 ; Z3 := t0 * Z3 ;
+ fe_mul(&t0, y, z)
+ fe_add(&t0, &t0, &t0)
+ fe_mul(&z3, &t0, &z3)
+
+ // X3 := X3 - Z3 ; Z3 := t0 * t1 ; Z3 := Z3 + Z3 ;
+ fe_sub(&x3, &x3, &z3)
+ fe_mul(&z3, &t0, &t1)
+ fe_add(&z3, &z3, &z3)
+
+ // Z3 := Z3 + Z3 ;
+ fe_add(&z3, &z3, &z3)
+
+ // return X3 , Y3 , Z3 ;
+ fe_set(&p.x, &x3)
+ fe_set(&p.y, &y3)
+ fe_set(&p.z, &z3)
+}
+
+pt_sub :: proc "contextless" (p, a, b: ^$T) {
+ b_neg: T
+ pt_negate(&b_neg, b)
+ pt_add(p, a, &b_neg)
+
+ fe_clear(&b_neg)
+}
+
+pt_negate :: proc "contextless" (p, a: ^$T) {
+ fe_set(&p.x, &a.x)
+ fe_negate(&p.y, &a.y)
+ fe_set(&p.z, &a.z)
+}
+
+pt_rescale :: proc "contextless" (p, a: ^$T) {
+ // A = 1/Z1
+ // X3 = A*X1
+ // Y3 = A*Y1
+ // Z3 = 1
+ //
+ // As per "From A to Z: Projective coordinates leakage in the wild"
+ // leaking the Z-coordinate is bad. The modular inversion algorithm
+ // used in this library is based on Fermat's Little Theorem.
+ //
+ // See: https://eprint.iacr.org/2020/432.pdf
+
+ was_identity := pt_is_identity(a)
+
+ when T == Point_p256r1 {
+ z_inv: Field_Element_p256r1
+ } else {
+ #panic("weierstrass: invalid curve")
+ }
+
+ ident: T
+ fe_inv(&z_inv, &a.z)
+ fe_mul(&p.x, &a.x, &z_inv)
+ fe_mul(&p.y, &a.y, &z_inv)
+ fe_one(&p.z)
+
+ pt_identity(&ident)
+ pt_cond_select(p, p, &ident, was_identity)
+
+ fe_clear(&z_inv)
+}
+
+pt_cond_select :: proc "contextless" (p, a, b: ^$T, ctrl: int) {
+ fe_cond_select(&p.x, &a.x, &b.x, ctrl)
+ fe_cond_select(&p.y, &a.y, &b.y, ctrl)
+ fe_cond_select(&p.z, &a.z, &b.z, ctrl)
+}
+
+@(require_results)
+pt_equal :: proc "contextless" (a, b: ^$T) -> int {
+ when T == Point_p256r1 {
+ x1z2, x2z1, y1z2, y2z1: Field_Element_p256r1
+ } else {
+ #panic("weierstrass: invalid curve")
+ }
+
+ // Check X1Z2 == X2Z1 && Y1Z2 == Y2Z1
+ fe_mul(&x1z2, &a.x, &b.z)
+ fe_mul(&x2z1, &b.x, &a.z)
+
+ fe_mul(&y1z2, &a.y, &b.z)
+ fe_mul(&y2z1, &b.y, &a.z)
+
+ return fe_equal(&x1z2, &x2z1) & fe_equal(&y1z2, &y2z1)
+}
+
+@(require_results)
+pt_is_identity :: proc "contextless" (p: ^$T) -> int {
+ return fe_is_zero(&p.z)
+}
+
+@(require_results)
+pt_is_y_odd :: proc "contextless" (p: ^$T) -> int {
+ tmp: T
+ defer pt_clear(&tmp)
+
+ fe_set(&tmp, p)
+ pt_rescale(&tmp)
+
+ return fe_is_odd(&tmp.y)
+}
+
+@(private)
+is_on_curve :: proc "contextless" (x, y: ^$T) -> bool {
+ maybe_yy, yy: T
+ defer fe_clear_vec([]^T{&maybe_yy, &yy})
+
+ // RHS: x^3 + ax + b
+ set_yy_candidate(&maybe_yy, x)
+
+ // LHS: y^2
+ fe_square(&yy, y)
+
+ return fe_equal(&maybe_yy, &yy) == 1
+}
+
+@(private)
+set_yy_candidate :: proc "contextless" (maybe_yy, x: ^$T) {
+ // RHS: x^3 + ax + b
+ rhs, tmp: T
+
+ fe_square(&tmp, x)
+ fe_mul(&rhs, &tmp, x)
+
+ fe_a(&tmp)
+ fe_mul(&tmp, &tmp, x)
+ fe_add(&rhs, &rhs, &tmp)
+
+ fe_b(&tmp)
+ fe_add(maybe_yy, &rhs, &tmp)
+
+ fe_clear(&rhs)
+}
diff --git a/core/crypto/_weierstrass/point_s11n_sec.odin b/core/crypto/_weierstrass/point_s11n_sec.odin
new file mode 100644
index 000000000..ae009edb0
--- /dev/null
+++ b/core/crypto/_weierstrass/point_s11n_sec.odin
@@ -0,0 +1,95 @@
+package _weierstrass
+
+@(require) import "core:mem"
+
+@(private)
+SEC_PREFIX_IDENTITY :: 0x00
+@(private)
+SEC_PREFIX_COMPRESSED_EVEN :: 0x02
+@(private)
+SEC_PREFIX_COMPRESSED_ODD :: 0x03
+SEC_PREFIX_UNCOMPRESSED :: 0x04
+
+@(require_results)
+pt_set_sec_bytes :: proc "contextless" (p: ^$T, b: []byte) -> bool {
+ when T == Point_p256r1 {
+ FE_SZ :: FE_SIZE_P256R1
+ } else {
+ #panic("weierstrass: invalid curve")
+ }
+
+ b_len := len(b)
+ if b_len < 1 {
+ return false
+ }
+
+ switch b[0] {
+ case SEC_PREFIX_IDENTITY:
+ if b_len != 1 {
+ return false
+ }
+ pt_identity(p)
+ return true
+ case SEC_PREFIX_COMPRESSED_EVEN, SEC_PREFIX_COMPRESSED_ODD:
+ if b_len != 1 + FE_SZ {
+ return false
+ }
+ y_is_odd := b[0] - SEC_PREFIX_COMPRESSED_EVEN
+ return pt_set_x_bytes(p, b[1:], int(y_is_odd))
+ case SEC_PREFIX_UNCOMPRESSED:
+ if b_len != 1 + 2 * FE_SZ {
+ return false
+ }
+ x, y := b[1:1+FE_SZ], b[1+FE_SZ:]
+ return pt_set_xy_bytes(p, x, y)
+ case:
+ return false
+ }
+}
+
+@(require_results)
+pt_sec_bytes :: proc "contextless" (b: []byte, p: ^$T, compressed: bool) -> bool {
+ when T == Point_p256r1 {
+ FE_SZ :: FE_SIZE_P256R1
+ } else {
+ #panic("weierstrass: invalid curve")
+ }
+
+ b_len := len(b)
+ if pt_is_identity(p) == 1 {
+ if b_len != 1 {
+ return false
+ }
+ b[0] = SEC_PREFIX_IDENTITY
+ return true
+ }
+
+ x, y: []byte
+ y_: [FE_SZ]byte
+ switch compressed {
+ case true:
+ if b_len != 1 + FE_SZ {
+ return false
+ }
+ x, y = b[1:], y_[:]
+ case false:
+ if b_len != 1 + 2 * FE_SZ {
+ return false
+ }
+ b[0]= SEC_PREFIX_UNCOMPRESSED
+ x, y = b[1:1+FE_SZ], b[1+FE_SZ:]
+ }
+ if !pt_bytes(x, y, p) {
+ return false
+ }
+ if compressed {
+ // Instead of calling pt_is_y_odd, just serializing
+ // y into a temp buffer and checking the parity saves
+ // 1 redundant rescale call.
+ y_is_odd := byte(y[FE_SZ-1] & 1)
+ b[0] = SEC_PREFIX_COMPRESSED_EVEN + y_is_odd
+ mem.zero_explicit(&y_, size_of(y_))
+ }
+
+ return true
+}
diff --git a/core/crypto/_weierstrass/sc.odin b/core/crypto/_weierstrass/sc.odin
new file mode 100644
index 000000000..2ed9459bc
--- /dev/null
+++ b/core/crypto/_weierstrass/sc.odin
@@ -0,0 +1,76 @@
+package _weierstrass
+
+import p256r1 "core:crypto/_fiat/field_scalarp256r1"
+import subtle "core:crypto/_subtle"
+
+Scalar_p256r1 :: p256r1.Montgomery_Domain_Field_Element
+
+SC_SIZE_P256R1 :: 32
+
+sc_clear :: proc {
+ p256r1.fe_clear,
+}
+
+sc_clear_vec :: proc {
+ p256r1.fe_clear_vec,
+}
+
+sc_set_bytes :: proc {
+ p256r1.fe_from_bytes,
+}
+sc_bytes :: proc {
+ p256r1.fe_to_bytes,
+}
+
+sc_set :: proc {
+ p256r1.fe_set,
+}
+
+sc_zero :: proc {
+ p256r1.fe_zero,
+}
+
+sc_one_p256r1 :: proc {
+ p256r1.fe_one,
+}
+
+sc_add :: proc {
+ p256r1.fe_add,
+}
+
+sc_sub :: proc {
+ p256r1.fe_sub,
+}
+
+sc_negate :: proc {
+ p256r1.fe_opp,
+}
+
+sc_mul :: proc {
+ p256r1.fe_mul,
+}
+
+sc_square :: proc {
+ p256r1.fe_square,
+}
+
+sc_cond_assign :: proc {
+ p256r1.fe_cond_assign,
+}
+
+sc_equal :: proc {
+ p256r1.fe_equal,
+}
+
+sc_is_odd :: proc {
+ p256r1.fe_is_odd,
+}
+
+sc_is_zero :: proc {
+ sc_is_zero_p256r1,
+}
+
+@(require_results)
+sc_is_zero_p256r1 :: proc "contextless" (fe: ^Scalar_p256r1) -> int {
+ return int(subtle.u64_is_zero(p256r1.fe_non_zero(fe)))
+}
diff --git a/core/crypto/_weierstrass/scalar_mul.odin b/core/crypto/_weierstrass/scalar_mul.odin
new file mode 100644
index 000000000..1781ac3b6
--- /dev/null
+++ b/core/crypto/_weierstrass/scalar_mul.odin
@@ -0,0 +1,204 @@
+package _weierstrass
+
+import "core:crypto"
+import subtle "core:crypto/_subtle"
+import "core:mem"
+
+pt_scalar_mul :: proc "contextless" (
+ p, a: ^$T,
+ sc: ^$S,
+ unsafe_is_vartime: bool = false,
+) {
+ when T == Point_p256r1 && S == Scalar_p256r1 {
+ SC_SZ :: SC_SIZE_P256R1
+ } else {
+ #panic("weierstrass: invalid curve")
+ }
+
+ b: [SC_SZ]byte = ---
+ sc_bytes(b[:], sc)
+
+ pt_scalar_mul_bytes(p, a, b[:], unsafe_is_vartime)
+
+ if !unsafe_is_vartime {
+ mem.zero_explicit(&b, size_of(b))
+ }
+}
+
+pt_scalar_mul_bytes :: proc "contextless" (
+ p, a: ^$T,
+ sc: []byte,
+ unsafe_is_vartime: bool = false,
+) {
+ when T == Point_p256r1 {
+ p_tbl: Multiply_Table_p256r1 = ---
+ q, tmp: Point_p256r1 = ---, ---
+ SC_SZ :: SC_SIZE_P256R1
+ } else {
+ #panic("weierstrass: invalid curve")
+ }
+
+ assert_contextless(len(sc) == SC_SZ, "weierstrass: invalid scalar size")
+ mul_tbl_set(&p_tbl, a, unsafe_is_vartime)
+
+ pt_identity(&q)
+ for limb_byte, i in sc {
+ hi, lo := (limb_byte >> 4) & 0x0f, limb_byte & 0x0f
+
+ if i != 0 {
+ pt_double(&q, &q)
+ pt_double(&q, &q)
+ pt_double(&q, &q)
+ pt_double(&q, &q)
+ }
+ mul_tbl_lookup_add(&q, &tmp, &p_tbl, u64(hi), unsafe_is_vartime)
+
+ pt_double(&q, &q)
+ pt_double(&q, &q)
+ pt_double(&q, &q)
+ pt_double(&q, &q)
+ mul_tbl_lookup_add(&q, &tmp, &p_tbl, u64(lo), unsafe_is_vartime)
+ }
+
+ pt_set(p, &q)
+
+ if !unsafe_is_vartime {
+ mem.zero_explicit(&p_tbl, size_of(p_tbl))
+ pt_clear_vec([]^T{&q, &tmp})
+ }
+}
+
+when crypto.COMPACT_IMPLS == true {
+ pt_scalar_mul_generator :: proc "contextless" (
+ p: ^$T,
+ sc: ^$S,
+ unsafe_is_vartime: bool = false,
+ ) {
+ g: T
+ pt_generator(&g)
+
+ pt_scalar_mul(p, &g, sc, unsafe_is_vartime)
+ }
+} else {
+ pt_scalar_mul_generator :: proc "contextless" (
+ p: ^$T,
+ sc: ^$S,
+ unsafe_is_vartime: bool = false,
+ ) {
+ when T == Point_p256r1 && S == Scalar_p256r1 {
+ p_tbl_hi := &Gen_Multiply_Table_p256r1_hi
+ p_tbl_lo := &Gen_Multiply_Table_p256r1_lo
+ tmp: Point_p256r1 = ---
+ SC_SZ :: SC_SIZE_P256R1
+ } else {
+ #panic("weierstrass: invalid curve")
+ }
+
+ b: [SC_SZ]byte
+ sc_bytes(b[:], sc)
+
+ pt_identity(p)
+ for limb_byte, i in b {
+ hi, lo := (limb_byte >> 4) & 0x0f, limb_byte & 0x0f
+ mul_affine_tbl_lookup_add(p, &tmp, &p_tbl_hi[i], u64(hi), unsafe_is_vartime)
+ mul_affine_tbl_lookup_add(p, &tmp, &p_tbl_lo[i], u64(lo), unsafe_is_vartime)
+ }
+
+ if !unsafe_is_vartime {
+ mem.zero_explicit(&b, size_of(b))
+ pt_clear(&tmp)
+ }
+ }
+}
+
+@(private="file")
+Multiply_Table_p256r1 :: [15]Point_p256r1
+
+@(private="file")
+mul_tbl_set :: proc "contextless"(
+ tbl: ^$T,
+ point: ^$U,
+ unsafe_is_vartime: bool,
+) {
+ when T == Multiply_Table_p256r1 && U == Point_p256r1{
+ tmp: Point_p256r1
+ pt_set(&tmp, point)
+ } else {
+ #panic("weierstrass: invalid curve")
+ }
+
+ pt_set(&tbl[0], &tmp)
+ for i in 1 ..<15 {
+ pt_add(&tmp, &tmp, point)
+ pt_set(&tbl[i], &tmp)
+ }
+
+ if !unsafe_is_vartime {
+ pt_clear(&tmp)
+ }
+}
+
+@(private="file")
+mul_tbl_lookup_add :: proc "contextless" (
+ point, tmp: ^$T,
+ tbl: ^$U,
+ idx: u64,
+ unsafe_is_vartime: bool,
+ ) {
+ if unsafe_is_vartime {
+ switch idx {
+ case 0:
+ case:
+ pt_add(point, point, &tbl[idx - 1])
+ }
+ return
+ }
+
+ pt_identity(tmp)
+ for i in u64(1)..<16 {
+ ctrl := subtle.eq(i, idx)
+ pt_cond_select(tmp, tmp, &tbl[i - 1], int(ctrl))
+ }
+
+ pt_add(point, point, tmp)
+}
+
+when crypto.COMPACT_IMPLS == false {
+ @(private)
+ Affine_Point_p256r1 :: struct {
+ x: Field_Element_p256r1,
+ y: Field_Element_p256r1,
+ }
+
+ @(private="file")
+ mul_affine_tbl_lookup_add :: proc "contextless" (
+ point, tmp: ^$T,
+ tbl: ^$U,
+ idx: u64,
+ unsafe_is_vartime: bool,
+ ) {
+ if unsafe_is_vartime {
+ switch idx {
+ case 0:
+ case:
+ pt_add_mixed(point, point, &tbl[idx - 1].x, &tbl[idx - 1].y)
+ }
+ return
+ }
+
+ pt_identity(tmp)
+ for i in u64(1)..<16 {
+ ctrl := int(subtle.eq(i, idx))
+ fe_cond_select(&tmp.x, &tmp.x, &tbl[i - 1].x, ctrl)
+ fe_cond_select(&tmp.y, &tmp.y, &tbl[i - 1].y, ctrl)
+ }
+
+ // The mixed addition formula assumes that the addend is not
+ // the neutral element. Do the addition regardless, and then
+ // conditionally select the right result.
+ pt_add_mixed(tmp, point, &tmp.x, &tmp.y)
+
+ ctrl := subtle.u64_is_non_zero(idx)
+ pt_cond_select(point, point, tmp, int(ctrl))
+ }
+}
diff --git a/core/crypto/_weierstrass/secp256r1_table.odin b/core/crypto/_weierstrass/secp256r1_table.odin
new file mode 100644
index 000000000..1a6bc3ef6
--- /dev/null
+++ b/core/crypto/_weierstrass/secp256r1_table.odin
@@ -0,0 +1,3985 @@
+package _weierstrass
+
+/*
+ ------ GENERATED ------ DO NOT EDIT ------ GENERATED ------ DO NOT EDIT ------ GENERATED ------
+*/
+
+import "core:crypto"
+
+when crypto.COMPACT_IMPLS == false {
+ @(private,rodata)
+ Gen_Multiply_Table_p256r1_hi := [32][15]Affine_Point_p256r1 {
+ {
+ {
+ {9259451175701532574, 15597985540941612547, 4541553034987877619, 8927802479718285609},
+ {14672230714928802576, 14284617950605306700, 13339970812390782046, 787078889494395850},
+ },
+ {
+ {18165439414433063919, 14693282888419586094, 14992616289789993230, 13232208150801553912},
+ {16850347485914337693, 223364064845089224, 7302899015436300563, 4391216311540396088},
+ },
+ {
+ {12558388403188680537, 10687978569513354810, 9373570856564649772, 4079327722512691465},
+ {5372437374337150740, 3297421622932790851, 9326853593823854687, 8305371884938201251},
+ },
+ {
+ {13121472331750731303, 323745485980480220, 15110308702528119977, 4696302365805118372},
+ {9859094500834571602, 5315656270700787939, 4187063204400651801, 1695695129564818327},
+ },
+ {
+ {12817586844019849804, 15425488216915741929, 15293562913126043054, 11770898970765978555},
+ {6806103820345670787, 17789094149138630459, 3807781571713999192, 5823254011289457198},
+ },
+ {
+ {10112524230916015604, 13571143908656270599, 6031089010487808103, 5774558171390644848},
+ {1808959243244841573, 14071312530426692155, 9241399242704553402, 9836150050655369231},
+ },
+ {
+ {14083007972403535491, 16009534514129505275, 12481249112231139039, 10309390659262581143},
+ {5782517315325366794, 16717384553294759530, 4578392002424884134, 239005024949492645},
+ },
+ {
+ {1836857790164349346, 11263074778654917115, 4786985732596838094, 10525445084936097674},
+ {1484357665966453236, 3110871407036679558, 1668700683093601768, 2736269131339849752},
+ },
+ {
+ {9249362594190920246, 8088172462140746331, 4080107866285682736, 16205599538438551353},
+ {18312943145606312277, 9100632964181080418, 3969991115337154345, 5340098959750368315},
+ },
+ {
+ {12122448407048035645, 2891250339380982359, 12794212052932523400, 7166035112141500392},
+ {15777441312724841162, 4552528682229856831, 2210391301762911476, 16410254680957321386},
+ },
+ {
+ {6910044784455706429, 11951245774670922855, 207795885948948810, 3884359690300962405},
+ {4578772752480772344, 2948797025787714138, 16774444535658202808, 1388183483009000463},
+ },
+ {
+ {16561979129019905420, 1881862411760441386, 15441950514711322010, 12933020223458438856},
+ {5570341451312029630, 18172638959728259059, 9074261777549091198, 6171200053222754816},
+ },
+ {
+ {10126435102176037237, 1545112930055760251, 11563139991870561593, 10766754172364938834},
+ {5116781688621052838, 14471715119500781375, 4724882615229687192, 10031687030722046325},
+ },
+ {
+ {15016829467434780812, 6777508689306592732, 3811682306063049290, 11475361222871876387},
+ {6080948654298953274, 11612742274762615033, 5268311600240325047, 9147351973710519861},
+ },
+ {
+ {12130203770930472759, 3880998309361490881, 8807462332494735511, 9291388074337055133},
+ {18165312304248982432, 12733144434841535979, 18090195697688236271, 5825342884125782172},
+ },
+ },
+ {
+ {
+ {194633990068625151, 1028128699653523895, 7436102537486268753, 1855520454959348468},
+ {5098690958966904466, 3342676718901330604, 6942212660412942406, 16510188838209674083},
+ },
+ {
+ {7963995066277321795, 14986230345162551366, 10616366460602472778, 16186943329215681149},
+ {9522855644164647723, 9858336437877021178, 16344942402271072884, 18027353494090590022},
+ },
+ {
+ {13392726161043192788, 7606793939450765773, 9543984695709321129, 6135912406103198328},
+ {10903991926178685177, 529801710637680784, 8207012095420105234, 4590962949922268360},
+ },
+ {
+ {13175608910844763921, 11168387468381338510, 5555873864224342205, 17780559602571640345},
+ {1582669533588472814, 8145133762789622706, 1625372887980692455, 4576809104068554285},
+ },
+ {
+ {17616803153811079355, 17809794753465712025, 10788493879428408032, 1263026253532745742},
+ {331896291298606534, 13299145463579793142, 8951131463540898010, 11121758705853021600},
+ },
+ {
+ {17015522374255846157, 7155392284047197223, 1248775493117789546, 9199472299655737207},
+ {13126885324657282947, 12092989376083683289, 2035698983314262432, 835441512024005104},
+ },
+ {
+ {12481871371020004325, 15786477648044981224, 2586272424816191689, 4208704695692543659},
+ {16940467964964992440, 11207566805119564978, 2858987625603639630, 9561510646236248154},
+ },
+ {
+ {2900978533555060931, 1749946807863203576, 11705734511931072459, 4446980691693419424},
+ {14437524160594907241, 12795912566640000773, 10400036254697939154, 8356113088668925361},
+ },
+ {
+ {3770654812111500682, 7723332701546321657, 12057007323752084660, 11871339027463593983},
+ {8927366002257844381, 331175455338905356, 6085376066711046662, 195998713859126244},
+ },
+ {
+ {15888580251537997623, 14253909833728698978, 14445538492667230716, 4028538972354525849},
+ {7720263170150940477, 1190890222876864097, 8657188516818851005, 1987613286973742753},
+ },
+ {
+ {1556082539082087499, 9191446579576007527, 16923484407567577707, 4662661048159090855},
+ {12760778972220173745, 3942937056545553996, 12952479961991875179, 8914103212381870290},
+ },
+ {
+ {8900726473285671992, 890209742292473781, 16059468388719373167, 16577940938542233221},
+ {17381766864962227733, 231915274132518769, 16477817024012878700, 15646021286310268545},
+ },
+ {
+ {10104554368814337641, 170400126349943750, 16051269335758964391, 7842493858299913771},
+ {9246756702190574744, 110682656515867335, 11402798562961521905, 17325237240525801251},
+ },
+ {
+ {15837018286366797690, 18114413810565810328, 9441874034567150801, 14075941137889189393},
+ {12786763055047269260, 9121030808281463204, 1713778999270814105, 17015261864438490667},
+ },
+ {
+ {12997570542605430113, 5500897611058123544, 4160129407772614089, 13768264346635084004},
+ {6638654171187871203, 6080635069726153281, 2255431148803290413, 3789670411999607189},
+ },
+ },
+ {
+ {
+ {1830819081327272165, 11951292080860646547, 18002500803418629938, 13317986695217403840},
+ {5005574200470766330, 10138179785738652504, 1610518863105278224, 13309443265578956954},
+ },
+ {
+ {14192194428653714479, 11578618567931657764, 6032668189933768881, 15981535562386193924},
+ {8925792218631314923, 9408714146004183681, 8859017894477140398, 1675606340537058506},
+ },
+ {
+ {3265119697568866078, 13753322853248061974, 15435163376825672274, 13646180516491714938},
+ {15620545622955090250, 18241486585498394565, 459566729126467878, 9728217493753855944},
+ },
+ {
+ {9883406233903270985, 17184231210468300584, 5498903678702785900, 6903833261382863389},
+ {11489138095102981636, 9021901931786177471, 3227433089132150317, 16639455550797627042},
+ },
+ {
+ {839045372102318861, 2032615141683118500, 1921816835840256924, 504869150737570005},
+ {15932184001422473505, 7849475855313305697, 1189994394722618598, 9874798350548229684},
+ },
+ {
+ {4636201671610663345, 16662311204732135584, 12398897461787695675, 1355753199357412657},
+ {14695655628527768564, 1692838776852698754, 7346906782826540912, 14869028424564984700},
+ },
+ {
+ {14240080119980315297, 4751983902385717684, 7941412103662252178, 4796803816695225123},
+ {9327986654018000413, 15111345676387005726, 3582558555283734415, 11913156735178831102},
+ },
+ {
+ {12915868875134296756, 3071143582305760275, 10848717856747030010, 10973183887638314967},
+ {5983269487036236823, 9885184706933333413, 14509493669845681951, 9669608065801379977},
+ },
+ {
+ {7848634325810890057, 4356492357483949442, 8777700982672429871, 447737364627887590},
+ {2892466086138453900, 12013259293340538023, 3423275627272380730, 11171074631447548946},
+ },
+ {
+ {14593553227914306527, 7393098159726367793, 959457858782426605, 12924066827318848802},
+ {14790800265003508462, 13805969419986022239, 4408523909823076864, 16722715416825698787},
+ },
+ {
+ {8554182115079118694, 17233907570567075631, 12336560627384786590, 5123566378696582545},
+ {96401035522143140, 10138155491929979850, 17651328686428132420, 3453390145222258032},
+ },
+ {
+ {16197242500758474188, 3349369240724295499, 9422940308750670637, 16888844525585804807},
+ {14045424784406071799, 13180603138700207746, 2683581192503868543, 3842875784859878},
+ },
+ {
+ {17498073686183419231, 6922314891526280784, 16083733402282932920, 15425477806093217459},
+ {12425976625898608391, 16458101989314253841, 10013521940061058050, 10858868879196007236},
+ },
+ {
+ {123600201037598181, 6690762836954208162, 17157040810691942664, 15263405971805161132},
+ {8685477170453562173, 10331174323986544033, 5789045082422148337, 3007978469441468974},
+ },
+ {
+ {2402095889286816125, 18054120920831753009, 11753130221915918396, 10341553510464463050},
+ {280903370426929900, 14994955837151914025, 13551362401871479612, 14711789630561753093},
+ },
+ },
+ {
+ {
+ {14086745261650819748, 17953107869776717888, 1777725846494438428, 2765314406831814212},
+ {2603997194371852991, 2223517025105045134, 15579901335531749634, 6571733615332171148},
+ },
+ {
+ {5478465698516556930, 287443454357750768, 12201204663663129285, 782849770204658255},
+ {11270045035009204251, 18152683972363144337, 10463300037926642739, 14363641589598863851},
+ },
+ {
+ {3790592075869665284, 5120320091554329756, 15361581282394028709, 14360464660911164915},
+ {15249656958991931940, 2563751872827049233, 13745792006936646733, 14572943674933168173},
+ },
+ {
+ {3167679014977537749, 3417445004776702290, 1709246158507866266, 5861367897285174360},
+ {8437429877561342262, 17231607446243478748, 16047596399306766948, 17656438585829685897},
+ },
+ {
+ {12977336347094692192, 13723871955002954132, 17399919575273038847, 16163973860244779675},
+ {14997921584659740746, 6543247361992425067, 4675926398794487109, 17580512382853194054},
+ },
+ {
+ {10778828023580771765, 9812611440536367405, 14168149065325522570, 6692229110872358750},
+ {11010962724400581057, 13055203605065073902, 11396463140731730116, 16969789651736772232},
+ },
+ {
+ {3285258013801327520, 14114268241282882888, 5367399533198476395, 17277410244918727028},
+ {2751895479568588421, 751309667192066167, 13038472116718581917, 16013586354334596135},
+ },
+ {
+ {12364168614988940500, 13194367252463423118, 12223406606527741280, 5014139294736037086},
+ {11244699482831816093, 5336498572491451990, 14268404582568856142, 14502318820969599316},
+ },
+ {
+ {13295673091232554814, 313981772853781347, 11829785736449464030, 13341198421333360997},
+ {16787450350663111566, 6525407229623764159, 2012189087039636323, 2110887590404698758},
+ },
+ {
+ {16984895766311549717, 1057465499230843916, 13565444352859773343, 1019268943988786852},
+ {2190009140530404855, 10045598732295352970, 4789803496780829836, 10700158388954091321},
+ },
+ {
+ {14840255112988420500, 10066628133368048408, 6527354835873855384, 16106607076894419125},
+ {3989024604987083046, 10713316697020150694, 16811389107269552264, 11294596059797019619},
+ },
+ {
+ {622403023838932676, 11423409007234191765, 17086830255702454786, 1213655124481948199},
+ {3976593910085142945, 6315875935390432543, 17947502153968859628, 18031540937011531543},
+ },
+ {
+ {342675887578148289, 18366454547938469828, 3853530442390999217, 7499455395579634652},
+ {768597405171336502, 1636271570683567151, 16786205337983572309, 13056241332863199715},
+ },
+ {
+ {15991153618414855143, 803325462494472241, 5709347424437559249, 10138502962472290727},
+ {4675124205115228106, 9599016746550345197, 2769443894695609085, 12311020551315051087},
+ },
+ {
+ {11470964304318784059, 17313372553735202469, 10686997186364536871, 9228453594798060121},
+ {57933324335302024, 8931389936300346353, 17823596478938529898, 1126996688113949835},
+ },
+ },
+ {
+ {
+ {15804957839814547154, 7924193945337173678, 1080401129055171214, 10816444561878528576},
+ {13171610473229361771, 8099842733764406841, 9284741070210451667, 9245195215372025289},
+ },
+ {
+ {7185947197544988797, 13306809398790059447, 11440959253278285287, 15084384140482244570},
+ {5059824327869316332, 7585354587200615362, 6801884469610571467, 6427162399794357267},
+ },
+ {
+ {1505501490785526604, 6062033360335279190, 13214531355927393851, 8869230490276248430},
+ {11596558698255017116, 6698268011950867978, 15445165013361223076, 4910055064120213146},
+ },
+ {
+ {1453348772281274490, 13028088570940491471, 16100623112750251840, 5210244400259879874},
+ {9443916155735416174, 16869520919318450506, 7479400208826706574, 14374970913352602458},
+ },
+ {
+ {13057495656815142976, 1743194961605203063, 15733599697884179267, 3501754291485677593},
+ {7405256272105757266, 12344297842308545819, 3389605493339498760, 3092252531918600248},
+ },
+ {
+ {5038191990715247960, 2723916483244871576, 4891019526710760134, 11094632341133260369},
+ {6274429941353136467, 1408871421293516065, 12455625869488488781, 3401549469990652817},
+ },
+ {
+ {4716563932720198201, 1584625214845878997, 13213357619008940082, 13122950207230795185},
+ {12303370001794463898, 6725033180592084698, 12302152314224424594, 6139100303374835750},
+ },
+ {
+ {10149597276931117465, 5778043705364022356, 13888443605241209218, 6889225091714429810},
+ {16209363638493043975, 8516350006446457646, 9214830076046105138, 8894115046323798175},
+ },
+ {
+ {161027176918876103, 2287100732338401479, 16561946444121779293, 9805329436091376243},
+ {11473978632757961256, 1245289731366992705, 7338435771556366282, 15749864527919116005},
+ },
+ {
+ {2753237807828198865, 11508305846735597339, 9058745440380813449, 3960739040735759442},
+ {17921955885187582871, 10231929062430218022, 18115018235326517243, 17854413167898372208},
+ },
+ {
+ {638684488109167329, 14596365931372343092, 1917271942976854297, 12291978018935761003},
+ {5076527739384635812, 7833625460571766680, 17060902137821849350, 17134703695475138982},
+ },
+ {
+ {13026208197163596446, 1935567165776196957, 17296090833026336866, 8461284827078097590},
+ {14545382879887213077, 3302103559307506085, 16026840048628844803, 4599071908983273604},
+ },
+ {
+ {9156540407095300222, 7598243263658987831, 1996711254516517688, 13013193687414837552},
+ {116495354444693499, 12803585308662671588, 8278106437192580735, 3374263264867687146},
+ },
+ {
+ {4318910866113560561, 8122780372606489166, 11952351993471767425, 9581759925599323445},
+ {12268585667545114307, 7286163136539353394, 12697490728074784421, 7270019569202782882},
+ },
+ {
+ {16247467139569457576, 14043942371464607677, 6338399572126720647, 9528527345786650933},
+ {16344656963096275115, 13804658662065732334, 2991248997774547140, 12174436388699549119},
+ },
+ },
+ {
+ {
+ {1169887957113173798, 4936710663791789838, 8029349457377894665, 3317691225106441967},
+ {3622769674498678594, 1954144360900150482, 1432045977341997899, 934737636789214593},
+ },
+ {
+ {9646181593082190523, 16068017411165381498, 13319927590045936565, 6113055520205251774},
+ {5576373032696512038, 13880344501714804196, 12022206929479211261, 7387979357081975315},
+ },
+ {
+ {13553890993911526641, 1237937561304731611, 11053651340854998814, 8737874920379363783},
+ {15414508226001886918, 9311523317130687807, 12080742822716708234, 4715194040021784977},
+ },
+ {
+ {17182132836049601530, 1486820395924546410, 14089047182364760490, 5375431386740917568},
+ {2352352269256972682, 6220398075470064021, 11444733678216077372, 8173002234516562536},
+ },
+ {
+ {7896339057146013415, 17613745684396593735, 4238258305077796259, 15438639564771394288},
+ {1482402451684594916, 3104492350488980260, 5195487229736262641, 1361150797580203482},
+ },
+ {
+ {15949855327936545010, 15892613064802301412, 7776232754624386979, 2193423430757249310},
+ {10751855334513902678, 13772090376350944100, 5644047706587449960, 370992037484721524},
+ },
+ {
+ {16329953561108738383, 14553061366216182492, 5112198484879130320, 1893048255589705004},
+ {11469678860036344015, 8992526488267920066, 18208245559304821518, 8980963391041920447},
+ },
+ {
+ {5783711159088718530, 3503029393593618754, 10736192136662142256, 15443859608128978668},
+ {271805305647187927, 8244170003029416464, 17017071503038388446, 2536084345379259313},
+ },
+ {
+ {9850291665987916519, 6499970366121170030, 7001995026899086280, 9961826319039756858},
+ {7497823327397141096, 6975352931548332265, 4068344268340314997, 15888973419716629698},
+ },
+ {
+ {3982898776583485812, 10403233710814076420, 8681461491810344216, 4116685619183896910},
+ {18192868132325233114, 17377077437999490605, 17997716263755054576, 10376686656480866118},
+ },
+ {
+ {3479412946560984795, 5044366097675527819, 13707564929638264911, 5666779920208401261},
+ {10137470376683230183, 2075467328249870088, 11457126564907274413, 13701087332649256159},
+ },
+ {
+ {12574253652565934836, 8388159655344384255, 16127953452716629313, 1877819316325313228},
+ {8945746653921217760, 4616678606113198065, 1336330019150074567, 11910289150769410280},
+ },
+ {
+ {9565592090082898867, 1968790057506790036, 4797721149040405609, 13125809848505545280},
+ {14122665390767023537, 17271175538744290850, 16007653062195668190, 16371835205840876479},
+ },
+ {
+ {10409691258933377688, 13736467137095186370, 2757793467881882435, 12443439690522935631},
+ {17601924849565694404, 988048065500720515, 7554063443268400107, 4274248596892038508},
+ },
+ {
+ {8972162505776549196, 16209364130421564220, 13018196697272262431, 418388148277092169},
+ {11645493996879973039, 5024734975063482607, 3708889997144620499, 11208942121415360714},
+ },
+ },
+ {
+ {
+ {17596113920958619489, 11920824479658301378, 3786905428099710821, 11112764289322906111},
+ {8817260450068629272, 6518847791514184438, 14593687325057339783, 18018581321332807475},
+ },
+ {
+ {2056254186648603335, 12143016575009965669, 3290271983033386616, 4338404082685850854},
+ {12660444972475266123, 6345409453044955404, 13278869140778657354, 10063005167581762786},
+ },
+ {
+ {5303950317664091150, 17409642188139937758, 12135894348302287058, 16444741243419918751},
+ {13935885817311324323, 8496908197501732703, 12163317723288843510, 16891353436915314685},
+ },
+ {
+ {4168420842704770545, 338440394515115377, 2102734009665481092, 9772725684473416465},
+ {1247616337419130000, 4222072446972129729, 4836898447189504007, 9154346000276664999},
+ },
+ {
+ {14649401370738987318, 10044081678892811795, 1306517740393103656, 16586067283450489622},
+ {8211832777731897494, 12849393859171286949, 17327526552807783018, 14171704619529498238},
+ },
+ {
+ {12849053390245557890, 12693731077061619694, 5891211584023409476, 1008960642219209210},
+ {15593393872187214387, 7381248773473326001, 16559656086795428559, 2106025108820858934},
+ },
+ {
+ {4347667984894353308, 2129883711661222690, 1076488804494872856, 15059968377755299195},
+ {12380937310378496242, 16425480883270944108, 4769192332535557551, 10388305045430499744},
+ },
+ {
+ {8553482596123775980, 12627020622203381515, 10774788686070344669, 6271789114731522097},
+ {6270586844349642345, 5584690155569770537, 9478526526319537174, 3405597782572827563},
+ },
+ {
+ {10255408065071335198, 2384996481315588922, 10679447117297819075, 3734157461055440416},
+ {1635042286365643780, 11321809677772938996, 2373960964139986040, 4869129159740273704},
+ },
+ {
+ {16681657814739017038, 2045405432090866328, 9473434018957974472, 5549808619751464269},
+ {3650191693776946828, 15805634549736708741, 16764187297356548667, 6849534466635874363},
+ },
+ {
+ {15295973549776084894, 8150873746601283651, 8017271980921908229, 4899654767305073834},
+ {15257501950484641691, 17365331272978440066, 14582514748324426172, 14727798284858071666},
+ },
+ {
+ {3180828552573045472, 17698570278585440462, 8986722854533057232, 4518665117523514004},
+ {1718699978312382231, 16973074530347269964, 5684175730451960274, 17228649521631238473},
+ },
+ {
+ {2897180423141326703, 13691273076814343144, 2967066815351306232, 1032540647518716635},
+ {16365716239989474776, 9503666134295232767, 4599017511227366879, 14475021161770955579},
+ },
+ {
+ {4512626226592149712, 13575110216387069176, 13488662643497927183, 9673147324484250604},
+ {143936220816719815, 2307325398241477161, 468315224038772027, 17743582630124600591},
+ },
+ {
+ {1476494936296433813, 3408612621327299295, 11632756669813257564, 14296719897220703576},
+ {2241234207239321749, 12237974399755684219, 16253635131573079566, 11892871179872526079},
+ },
+ },
+ {
+ {
+ {9440495138081785154, 17328162383695942099, 1870751290505230781, 17987066187778049275},
+ {9952223038481207705, 10126409487298126876, 1181369784146909444, 8158422380540037915},
+ },
+ {
+ {10892870009313407934, 5709686117526627488, 16343828906887149047, 16063790174205876315},
+ {9076070192754075075, 4639156357669822592, 4904064385440242264, 5942264027390072320},
+ },
+ {
+ {14586043427955633062, 1886633882927769308, 12786104261802569226, 17414735423561048102},
+ {3869682486341171982, 17146691898427698057, 9886217016173201579, 17515773620461053745},
+ },
+ {
+ {17271984572727555145, 2097715321690717305, 5328035183708920909, 13206781766168781008},
+ {5915693606819932446, 3870849056297265622, 18070792155150730518, 7786839743829304936},
+ },
+ {
+ {14091274565690260814, 5039742420071412611, 2322945829654574283, 7678395717670225646},
+ {17396071770599775867, 4747582460834310767, 13387178106758137047, 7224458787360678986},
+ },
+ {
+ {2020583809775623843, 3803516109208330416, 10492323079463714031, 18244921722581618682},
+ {6400055933742731191, 18370212581946723247, 11415812944884122048, 5987324147127294665},
+ },
+ {
+ {3106709870210381627, 3437108621064387068, 3265644153772373951, 14353255805499610949},
+ {11329727508866046420, 5461257448868659690, 8139681370942905079, 8439558396411914298},
+ },
+ {
+ {7939886940063870939, 3597929036186322512, 12732772396498766041, 13300425267730247515},
+ {2345112231224079293, 12327614629296314761, 17106102937162407683, 1702694317559034053},
+ },
+ {
+ {4276582831142955483, 1304336253044853784, 18317056640605949326, 11200473213973297420},
+ {3937030502759894542, 2315314353886242360, 2673827662906962132, 9781744582918546067},
+ },
+ {
+ {17837268310687096164, 10122495457633601623, 11985150009870152981, 11282144500794610389},
+ {13999168735732598559, 9030771445951876212, 6423904381826094276, 6148980837201061250},
+ },
+ {
+ {14621142736654260750, 1806201536162806753, 12562675185535659971, 5326177198980139868},
+ {8675433132905478434, 10796034085894917871, 7562073626744691385, 1491977564717017512},
+ },
+ {
+ {8821632341545057929, 16708916351043551467, 9171560460858577216, 5711973041149612575},
+ {15808302665077457285, 8412173943543358851, 12602476370021215716, 4778674887660148537},
+ },
+ {
+ {7524796586818405222, 5468491023058834244, 7965536127579551161, 9575670558568595724},
+ {4020611179055350793, 186082735900253826, 11198349470461895384, 2693853052562145978},
+ },
+ {
+ {7977371007734934919, 1442746893361509157, 15080044066626816201, 9179319344686817504},
+ {17927184654813605164, 16541635384799094673, 1663389722548868092, 9157422724003022421},
+ },
+ {
+ {4167146676307544690, 12042136744739037957, 6606952994938338836, 7554398412699794678},
+ {11844277247778765775, 8165791089025933303, 14954338535964037723, 16693854111477654477},
+ },
+ },
+ {
+ {
+ {5841260956815214452, 9461234662498869948, 4761949640006529525, 18229823346336752572},
+ {16055957459773168413, 4272222475092786627, 18249888117586812770, 4531982814021269346},
+ },
+ {
+ {7270238601276019194, 7318279377964882079, 5226788506940171017, 16838449902078450273},
+ {3375184937745100689, 16320655850583231520, 2173229791272659780, 9816381971766204380},
+ },
+ {
+ {17113448198982970082, 8879656883528014268, 15215762680430094206, 15232212751792759071},
+ {13699137317730183483, 11815206710130297569, 12298409691055054593, 2192455093917691024},
+ },
+ {
+ {9742819322069712752, 8779224519997661749, 2591205872359340025, 9144644967919881415},
+ {10495832103710459914, 4557264342687723360, 935865282128150338, 7120324256648044882},
+ },
+ {
+ {4683169301229531061, 14940390399739549639, 13128742567354398401, 15222231511210090535},
+ {7352694898928671332, 1221555526903686446, 8697118143614336514, 14515400523185205597},
+ },
+ {
+ {10239864229747754958, 12477284975467600510, 14054830413782031834, 17752968481181892755},
+ {16082713391521411762, 17191329716867535304, 11245514405315337909, 15159733745232554536},
+ },
+ {
+ {15444441705629456398, 12030687282161152512, 16500102437404896225, 11467410246278043769},
+ {14031300093087427598, 14458597378298191386, 9434445586505481169, 18221119130471329822},
+ },
+ {
+ {12694666558858009121, 10992313774737315187, 6046508760845509477, 16818819584649823054},
+ {10464090160691032219, 1221502600750419478, 8658907655588546849, 16110628890984509877},
+ },
+ {
+ {14304143349839262251, 13048055876309896774, 8676204847923624352, 8365498293767636038},
+ {13565995665971214654, 10895028049457785231, 5911971723937387023, 8436244239466286317},
+ },
+ {
+ {11501032393232899227, 3895174794911924947, 3230698222875450976, 7264134402609589101},
+ {18091100044992147344, 13252184705645692134, 8424205723200969631, 5731735154358029264},
+ },
+ {
+ {12163905774765001813, 3911227235818691672, 9833792088244333742, 6413344327541478453},
+ {15325942369130325853, 12629318625161567307, 8784755949357111975, 9462269284575183222},
+ },
+ {
+ {2157617452419341992, 3753997642171159286, 6553292364671628995, 4814048166016850277},
+ {6152139240994642263, 14066819599579263267, 7377541740373798192, 17830582976167057789},
+ },
+ {
+ {6906089045659836134, 17967958089618664024, 13353206790928340833, 14671934547763383296},
+ {12187232481950713594, 8718528695481423527, 18137604428804898613, 17758096361511845106},
+ },
+ {
+ {17646581888040948752, 8252837592394234071, 2508742924483223473, 5332070238932154531},
+ {13165985796861395246, 4409584176627274781, 9230253121183107430, 8784052955551358471},
+ },
+ {
+ {5394535031187713437, 5279515585052353937, 14159976884067043134, 10130852155763718010},
+ {13777927158878861230, 14015445621678244733, 3350717438960860318, 7071836838770144750},
+ },
+ },
+ {
+ {
+ {10708602749843635238, 8046488591192123621, 11391158257016334553, 2512908912806916201},
+ {14760224624269838038, 2631910198880826809, 2387247811669872033, 2048193899742148806},
+ },
+ {
+ {17392983665205025720, 12603331233691760840, 3752711326309791976, 8281544857330094164},
+ {17004651346561270106, 10399322540256775923, 9721299450284863176, 3725182263994944884},
+ },
+ {
+ {13643198694788276032, 8127425924819487897, 14165945065582850538, 16520977003164405917},
+ {1941948502806705647, 12390949208067741787, 17112117376594486408, 10232906951259490042},
+ },
+ {
+ {74190110112564319, 11227229657066745164, 10151080599595091944, 16591051376074591375},
+ {8256332495682655293, 7127985739945537626, 5708687346183367016, 18310921046455023281},
+ },
+ {
+ {10040565835468209502, 3986586816478505371, 7957179672896506016, 13347112914739722590},
+ {14099734293320932556, 13921950344400895005, 17478414833301838037, 961445463330402797},
+ },
+ {
+ {10553899634420153414, 4215979268474142438, 3643081140297634139, 11620906704125380460},
+ {17733628678553828301, 137473878710304143, 6211837577294956591, 13926110616399428016},
+ },
+ {
+ {15203257341351417031, 11597829209697937782, 17317571979811895272, 15929491640570317745},
+ {5731227916276913121, 17093153916149088230, 3908757069480556294, 18211818355208735794},
+ },
+ {
+ {6887629766078662088, 15330755394432598442, 14144608177273202986, 13258654996547018856},
+ {8975611270007504091, 16869834856279102361, 12707970875852047823, 8520055680055874514},
+ },
+ {
+ {1643407997152867899, 5400650551136488814, 14663391437159245064, 4743209938058826866},
+ {1728998201888511561, 11238331920657195520, 11617984741897247805, 13858029141809651878},
+ },
+ {
+ {14003691155137683825, 14641672309228817657, 4031783205073356111, 7414359968614421153},
+ {8166814052414482491, 5209260157266028169, 17555696996149558694, 9780166780476833956},
+ },
+ {
+ {16029688335186691281, 4244772808651443261, 6450459413414527821, 695875191412722741},
+ {11104054226249884864, 146461617619843327, 17480214580411209436, 11285418463967817315},
+ },
+ {
+ {4922928863857449168, 7226901725606965824, 7568276305032368752, 6253457805758596797},
+ {14345040877576203078, 1718759302498746946, 3544444746772280646, 17880302727399449566},
+ },
+ {
+ {10693864548794383214, 736148233485985101, 5241869061152863453, 7166954323782542739},
+ {16861482585847848251, 11483636939866570861, 5950529069765100144, 700887039653157350},
+ },
+ {
+ {3906969739692830848, 5546431121705298614, 10491799900914853406, 5871175286230239238},
+ {2851574662174517162, 5511397532379144624, 17409985391224790540, 319012646822749823},
+ },
+ {
+ {15269778527761027251, 16471737837294177924, 8830398856035267114, 8206807757132984992},
+ {1421214226977370752, 14233751335943482739, 9668238787333455452, 8700964319357541954},
+ },
+ },
+ {
+ {
+ {16477698187919702699, 2757160833848759781, 5976267476122243443, 7375951277779829055},
+ {6525111513935493528, 9969722922172879681, 12582700753056539952, 3861958159147836631},
+ },
+ {
+ {6001837395299394988, 7545846298204709215, 6662102781970969966, 12696054550672669874},
+ {7436995610194789060, 9042605089262227561, 11621508125069628605, 7289479057360149973},
+ },
+ {
+ {9447061002880879247, 14620964119546151815, 12310553083192998735, 15923694411935453454},
+ {7392925129127637753, 14135139889986895975, 12760571438361221130, 17000514617803354735},
+ },
+ {
+ {15555649500689005370, 7857014165815014600, 4664069234996337119, 8058230521837307501},
+ {18090421626009183450, 9278179697462444898, 17138879353097908770, 18285223269807746171},
+ },
+ {
+ {6099842409325199202, 2732701612070195412, 18229871238556385053, 10275023622778520796},
+ {5986266691884320152, 9796109565274465130, 8132405984970989382, 4521405733027618902},
+ },
+ {
+ {7427469853953577123, 9581104712231034671, 1702722776800247878, 12656779221313783543},
+ {17977155285174544822, 7208039998659519604, 16978428797146101290, 4487821481774245164},
+ },
+ {
+ {8040999562333134211, 6854344540855006667, 2481534773419348751, 15571316619985340537},
+ {10089854957334316687, 4775911690791701632, 15619815835608539594, 336338508421162031},
+ },
+ {
+ {12741225973381753432, 5461579923265799106, 4348015554411389960, 14970536173310927872},
+ {11568371199139699619, 11748662751675667230, 15495664823061891700, 670495577617908409},
+ },
+ {
+ {6065163107315563308, 10179715614080542168, 15046885616273736618, 3965401047645186422},
+ {7013093813183571821, 6087826007582017410, 14469686436525543908, 9620661780899615891},
+ },
+ {
+ {4469547109588409455, 11124190799085603197, 7471495874998642156, 14754586999614006506},
+ {88849924092797594, 3031352551776027825, 15701321561580429717, 783416358537121491},
+ },
+ {
+ {16899538363784443428, 1224176808212436099, 8044883358999763192, 8119246882922976226},
+ {1602185320898819533, 7795133078900055750, 15379182653822915088, 11717676755990779936},
+ },
+ {
+ {9865772269601493999, 7325690007062740244, 18437964667185475354, 9546360111100619473},
+ {6266116854923135821, 295905071295541234, 16037468634731642095, 16602609756229843150},
+ },
+ {
+ {9871952371310035629, 16929106233175362415, 3445554197529258762, 1598752868683659684},
+ {10123732080482057842, 2393692486932623922, 2380673894473467164, 14578017559552626408},
+ },
+ {
+ {16688239163561330036, 11170579336923472003, 3699145675255553709, 3266133724446548264},
+ {13646430870088709566, 9802235972068927845, 4016187574117121322, 8646347483626678378},
+ },
+ {
+ {3473609455134319994, 8666646689587058890, 10588670228528079578, 1636194164122827747},
+ {10443498896203771168, 1711092164750178258, 3641509682909832777, 11037852869436666140},
+ },
+ },
+ {
+ {
+ {15254713655124736464, 6283719686609422435, 5417864180357938798, 14010638809605797246},
+ {10873690600705871523, 15014239467130590294, 15765460219545280655, 6048061577845125750},
+ },
+ {
+ {12012729503226546642, 4811951115754240681, 2652621264600062520, 1108958391967017223},
+ {2508980100759035797, 9023233544151778447, 11183557587641545146, 10726727280840759519},
+ },
+ {
+ {396296174223428093, 16763788748988621834, 10606803701784640909, 2399987183687936561},
+ {3641562114746393614, 8536687357022564742, 14532545286961725758, 14658331097531946901},
+ },
+ {
+ {2386026063595321071, 9144724461940169335, 13121187420621518554, 17351696676224980491},
+ {143495028693925520, 4590642171152119027, 8655406817079059692, 10005507077955932112},
+ },
+ {
+ {2047964090310465728, 14133690277069748515, 8287749071957055844, 16821270580974431218},
+ {10324684883587585565, 9652498187344172497, 2461802306013063247, 15048850312040680643},
+ },
+ {
+ {105705035058376953, 7541598459498134635, 6627685529861836787, 5724525771392188178},
+ {13865897118300842617, 627652561624109853, 167084371112939132, 14192831153344015422},
+ },
+ {
+ {12837696619944805389, 13470316523008526719, 3074966674353053986, 2630814767089382743},
+ {13353767941686870870, 11405513520090968568, 3071969598389884693, 8212421686942839224},
+ },
+ {
+ {3464453985305889088, 7486900500389940957, 8944303108517222303, 18319933556403836918},
+ {6782476025105836770, 12822840946923377510, 2799592944286097404, 8737598030273298051},
+ },
+ {
+ {170025682710985810, 13049055489275530431, 1714038719952287416, 8470425667049459662},
+ {15692449588624337561, 6306908925988159475, 7292362624201217567, 10084542069209889549},
+ },
+ {
+ {5788423445465760069, 7489854375947810149, 2512436350424132958, 18422682564857699600},
+ {5177251288327577128, 13879051611542381588, 12430182880452441435, 16367520376757404605},
+ },
+ {
+ {1828702178325893477, 504110179554648546, 13285173922848349127, 15811513724231368560},
+ {5009291056218383875, 12726125712718222937, 2511326207435121241, 4878070763721166868},
+ },
+ {
+ {3151967592390934907, 8745573685636820318, 6591530195811780291, 2269684725432150574},
+ {7575618284647930930, 14430170051221190457, 17370623489799706048, 17190167628015666439},
+ },
+ {
+ {13971505255871035961, 14447456703883945351, 7749508685925819836, 12281701633335081378},
+ {4638096293890044597, 16388439049639616700, 2805317369196495081, 5611057071508020450},
+ },
+ {
+ {3416635149605340108, 10996030428276056653, 14121021550848949146, 17748729969482499931},
+ {12079053778595035959, 7473419378019222577, 1862205264236631673, 13655366704192015583},
+ },
+ {
+ {4817911180954611512, 14468615228783100826, 5900448495927012352, 2522071476550218088},
+ {15649024877429766334, 3445298745493942789, 2295617386899137580, 18376023059372246253},
+ },
+ },
+ {
+ {
+ {5228416958727036186, 12534300056259911378, 6859045937063682340, 16561718753727911412},
+ {9427589074776024847, 4167904055656501509, 10156691045253563236, 17557096561606923049},
+ },
+ {
+ {12847261474293104380, 15935635664155479706, 11956861064550631146, 11743590506948225647},
+ {15973092866215748716, 8269726904881958353, 15639962392523441528, 15171417818360069012},
+ },
+ {
+ {2605212343977737441, 18393471024186189813, 2302707671753008158, 8606549841034095192},
+ {3842822953634987820, 3094721493917442423, 6408313759447502937, 13486364200254727287},
+ },
+ {
+ {2191808101092881088, 128992526124656216, 738676021426139131, 10157323147642681558},
+ {11221959943853120586, 18255489816550713347, 10885231659068427649, 12104397395119665023},
+ },
+ {
+ {7707807226411417919, 16609863548699265350, 17639371636697428128, 8755472387723764172},
+ {164779854477783265, 9714199241756765614, 3491355372893948450, 17683742455036967163},
+ },
+ {
+ {13595758632462338296, 14515163666150177917, 6720823780841221770, 15071435664343609336},
+ {9016075014492765983, 16881277609836316886, 6969993988115170067, 15419704786434737070},
+ },
+ {
+ {14933348768149415725, 8499210770493553168, 6778840616148281272, 13282837866452012488},
+ {12007326272174861053, 11172739862019218274, 15202495365302649711, 8797477675597086120},
+ },
+ {
+ {17862558746132168231, 4941846130090682869, 17131557654945008226, 5312800819142473968},
+ {5818269467205924209, 13458582047859447022, 2683428091382447153, 12956887954464730664},
+ },
+ {
+ {11820752998821943867, 5623379642132478491, 11666807493120740820, 7241997274572162616},
+ {17165010508995490690, 1769225877906480182, 3814296306467163522, 1913823003062817434},
+ },
+ {
+ {11936813336110488997, 3878433838529606580, 6540053284493149566, 10610279324743393563},
+ {14079852809920102066, 9176732841330794388, 14287311909822853963, 7146204303626670196},
+ },
+ {
+ {1222343790928490335, 2199405396044383670, 14080919887213592148, 7341303626667347624},
+ {11784881532696657518, 17307742911086150556, 6036132721599132043, 12167106497065306941},
+ },
+ {
+ {13817073203406999359, 7220729284169210756, 14908407498603601482, 13536224989620701632},
+ {1615171540711527931, 2063856048260214664, 10622581435417474559, 16378505765730768032},
+ },
+ {
+ {6855676470217754770, 9517149712286624325, 11080380031068971680, 667425509348698033},
+ {6136243307299269825, 5326577850303193160, 16120190278345757447, 1982981965726975383},
+ },
+ {
+ {15399454106099176868, 3988744407816581672, 3596277710300384050, 15129113714633923498},
+ {1554582462382333698, 3164553872715651710, 12729140363982748426, 16366728035709811784},
+ },
+ {
+ {11647936211409428873, 14704462653811533865, 10005129575282387925, 1526194796943187368},
+ {10906326807488904308, 18256878690674435807, 13093574545395154003, 12352810226542367406},
+ },
+ },
+ {
+ {
+ {17055119974261943875, 6266720893662254540, 13102139953381148874, 5249314164321788611},
+ {7157525732140787612, 15381277459195914226, 17265025258266710353, 17573500432599548120},
+ },
+ {
+ {940679263188661008, 14653357165718140350, 15439920797347843673, 9415587255510557494},
+ {18115037054677722678, 8165849408798239027, 17369387099667572407, 17619066457126678815},
+ },
+ {
+ {8649149223282317557, 7756351751136698462, 18239772072009739451, 9817506578949224559},
+ {18378033667730800420, 16794121140066562876, 5288247581483071333, 12402303517382928119},
+ },
+ {
+ {11047138821675365077, 8918121441180891972, 26692501222219426, 15248413052700323978},
+ {7305399157133896461, 7065644238942265367, 3949166834387057064, 14178248206708015607},
+ },
+ {
+ {2031270890855333638, 16982096442429440651, 16686304398848635900, 5829842366016448839},
+ {14111080098472974183, 12565301877743332219, 1685254887702201709, 10638099573980009130},
+ },
+ {
+ {9618597135962048429, 4323708363301758294, 1934098864729515110, 12038442338797726450},
+ {8373847126955513333, 3300151407444969023, 15888126952439796914, 1426880256839266097},
+ },
+ {
+ {6428576619669681259, 7657770350257045071, 17839413659396163406, 4702043961312931605},
+ {8200928556018997183, 13282376860743810804, 13005614455417667639, 17419029631791664639},
+ },
+ {
+ {69860179712677448, 15464996655458230480, 15095351218136595554, 3792171085643513009},
+ {3187131848664503636, 12713332789590787064, 6278731049699775392, 1597379696359884724},
+ },
+ {
+ {15673011075664376010, 15519225812231888543, 1336371877669824820, 4354970830277120843},
+ {8744720488959125220, 17541792919601146935, 14299260104084112815, 16082554294713598652},
+ },
+ {
+ {13540612390708052286, 10213354985487483900, 11366371415587713866, 10334937577432263044},
+ {13368390835254255145, 13453645319717588760, 6303196127329783110, 1204334422768264234},
+ },
+ {
+ {18221540219239501535, 8536815826205784644, 17328509446048600304, 13923028809228258331},
+ {13984621134784540482, 10254983270679630247, 17457131706329229663, 927850905006752032},
+ },
+ {
+ {3952205381894147962, 11371446109407143937, 7231851263356642380, 11612512368538303138},
+ {5227214975837085115, 10737565048439707166, 6333629542995218640, 12386725921557807638},
+ },
+ {
+ {3772067962000745672, 4436468403847408320, 10612599615182677580, 13738755391074136269},
+ {13665557786177426407, 14568219921857752, 2691062926825113708, 14666515738377567975},
+ },
+ {
+ {5392936538333570234, 10526292103645946001, 14132494129869423619, 7207059073717065545},
+ {283545293669631007, 15845011600683983526, 5081287846871250008, 17931854980704528162},
+ },
+ {
+ {8364400939527235175, 7959571573625351093, 15849019287994534535, 6982609389731776566},
+ {6287382484291579264, 16496145344132275167, 12062306229709713775, 312030175316686885},
+ },
+ },
+ {
+ {
+ {17224650011872599657, 11430188086182976152, 12892063618843720029, 5912993124689510433},
+ {7069617917494051681, 1298012103142698333, 7943359430865057535, 9329776843721719539},
+ },
+ {
+ {9464085603669036454, 7848014338005901108, 2368914226155404065, 11578416111848517850},
+ {6323647866244499941, 14399589996703947996, 2824522520842155768, 391310842153371124},
+ },
+ {
+ {9948650801233133770, 5836115460383443197, 11404170696974449207, 4791020823967734476},
+ {423024247809958592, 11251668387880260801, 5562546584223492723, 578572156618131794},
+ },
+ {
+ {13988854693674964723, 10817154032069031941, 3171651998645961547, 5518712225783687705},
+ {14706905091132091970, 13960758460934966876, 12141035142079693145, 3149939820435101269},
+ },
+ {
+ {2505301881938098126, 9962323478923652140, 9312199523950444342, 12957822502673689705},
+ {8060810607849163143, 737408553843844193, 8143568733429881786, 18003168270780769476},
+ },
+ {
+ {4460927228453411137, 16058422703785787527, 8016770980039986075, 11450941100964860520},
+ {2742597710491507274, 16940752978671801273, 5897441526901650840, 5926672707007682446},
+ },
+ {
+ {5772778048593061508, 15424756817708323928, 11842041259277183807, 17669952685051160523},
+ {5405007811515938363, 4415223809135251038, 2223192286456742546, 15742105795795272774},
+ },
+ {
+ {11809342655313500273, 16822704101813284237, 13097372075606737923, 5463281428453250615},
+ {11967866991673525562, 6828790575157689223, 12568831962097805646, 8385980093725157349},
+ },
+ {
+ {8090324765778815982, 15997433100218204643, 7771766025433829989, 914551143312324786},
+ {4640358803642182649, 17428148208737756210, 12144967737399770998, 15075125743380741412},
+ },
+ {
+ {5954807828598238451, 3186352433639831389, 333598278340882889, 8647732331490039308},
+ {3706589107409903019, 7338319463305947507, 3829684452513478938, 8551967121356509963},
+ },
+ {
+ {16753777599759754869, 12028154198579512953, 7911616552276519044, 789841268294170739},
+ {8228995103825761982, 14293958931719060336, 2778055819582565008, 1399082948378499882},
+ },
+ {
+ {12492565198527218900, 17337285577296730202, 15088344513573802417, 4272568906387671217},
+ {2365541522321646412, 678395397666822608, 437334842774934301, 13443327606166079837},
+ },
+ {
+ {1266313952277763194, 11470850617813390661, 10426389264474337810, 2996447663006153747},
+ {15218295359022152122, 14634539952819815592, 1775270187047190460, 2942637199921677956},
+ },
+ {
+ {4952377176677649521, 7473631065005310719, 7363684030854414233, 12556891399998587233},
+ {2190850394642244911, 5458637782288631421, 270926994697866523, 5528436328062366401},
+ },
+ {
+ {9497175173535366966, 25345745857275253, 5047829133239508177, 5340238103822773099},
+ {3133339556064328840, 666970525709876149, 15575505473500291502, 12769675806855640654},
+ },
+ },
+ {
+ {
+ {7669790431656261769, 2776517632462593286, 11694025667665633506, 9533794089008895277},
+ {2895611631120558023, 11551410655448788956, 10026541900772270925, 6243136875017000843},
+ },
+ {
+ {9434484992529186384, 16435748047660609525, 16190660694150989986, 7083965852434071085},
+ {4216306437741910756, 2698742177539497614, 5199793642504009017, 17298424769819019160},
+ },
+ {
+ {4041169394784902550, 5699517344009382913, 5306272267462320559, 15846674482556330025},
+ {2606351264228884283, 4162585980422107281, 3715151019132039005, 6607223447043258693},
+ },
+ {
+ {8168579295855409503, 16727569921530031841, 6182114460261837773, 8940603165471931374},
+ {6081572078077526926, 5890840443923124563, 11215305828294759727, 2875117534361804712},
+ },
+ {
+ {9045974983664041829, 905036705033699463, 6962033946652121779, 3027264198782618401},
+ {13786415307358010100, 3643342525745067473, 13641958783381681886, 15675065537779359584},
+ },
+ {
+ {7507377696839752642, 1061259379811757443, 10276590160392917813, 6889137095037822679},
+ {16373913505782725550, 12287733095803524526, 5695917172259210496, 6360958736925918808},
+ },
+ {
+ {7459854586357006968, 702429387211615855, 8231296036461604410, 628323703857882004},
+ {1059802628602873385, 12517208225099517507, 2368172548334856593, 4792344750094708709},
+ },
+ {
+ {18352334786472886037, 7096021570596476676, 17045407505128867173, 2467670847537319400},
+ {2225663888244226889, 1876713214939672742, 5329943993157142620, 12168650975912182188},
+ },
+ {
+ {6639850268372381409, 2284514769224558945, 15390110317831975716, 13933785559694229008},
+ {12787641603764341997, 793886210532292741, 3222136169196008839, 11104892506868626444},
+ },
+ {
+ {12660547967989039787, 2109392063597767300, 9889743271997754037, 11803327596624324036},
+ {6940409327849314286, 1466399127363116843, 2572333022681966275, 4216097356402537802},
+ },
+ {
+ {16858757460581672909, 5838407119753001493, 4453405435911954669, 2828665451507432751},
+ {13657966632733241760, 6875986784381874300, 2390233934255482553, 17386653779125555159},
+ },
+ {
+ {2976756344404126744, 17032556609402836559, 16348907464011574182, 2196781021202618892},
+ {8270822867494340805, 4738372358350764889, 6088256422707334932, 17121369334507507505},
+ },
+ {
+ {2081729301541563384, 5577186154173396778, 1865152567701500436, 1422284589642218069},
+ {2489023909725140903, 276494395149046869, 17420927169263487236, 8292343688801608074},
+ },
+ {
+ {7819174654675104600, 12778055482430336726, 14615848543490171611, 17498415175263742825},
+ {4785899184222234034, 5227136636239697699, 1570704808469050246, 2858953380860123257},
+ },
+ {
+ {4323577007857413306, 10524228743339400397, 5418808897687027557, 5939367271366264075},
+ {3569359126353670574, 12961495213964770607, 8906990808988099905, 261084295374207271},
+ },
+ },
+ {
+ {
+ {14408045416865494124, 2442199381796557002, 10475326303775862953, 13637445125954159957},
+ {3778313603630758744, 9247460369874272772, 17572237597883145087, 11338350096360776602},
+ },
+ {
+ {4336697789732072031, 16054848662858822197, 17934449813415035557, 14518380622432694666},
+ {14100582434152190048, 6262866632984449325, 18069160441815400774, 9798342103009260692},
+ },
+ {
+ {17244020587062193870, 7625407515295016845, 12692919397126044801, 739129074276464779},
+ {977900962655641355, 1516169712468716336, 16875961107875019625, 1582931498538195018},
+ },
+ {
+ {687104890149081183, 1938816743979859301, 11342071981175913904, 4270322127259097184},
+ {4964776270155503160, 17849333582861534767, 15814479527332819692, 8083943565773123408},
+ },
+ {
+ {7977186743666958490, 3126199553548085949, 16879636338977836444, 16647578924708995556},
+ {5526017172393528596, 11328754652335568585, 8095074058116436597, 14648690727521713743},
+ },
+ {
+ {18335678403814425235, 13764304056086998207, 18139296224460762074, 17620705673387523052},
+ {16059975647897396183, 14392541906869470064, 13641721532745636092, 6122032872822720831},
+ },
+ {
+ {13983401929934353021, 13860725962778449344, 11760533704789481157, 12566657951327299627},
+ {14697122142882732522, 1606632877136342124, 7872716135734366961, 18220536079227927821},
+ },
+ {
+ {3986890035154628803, 15316660330065019741, 11560940574529263780, 12576851520091035878},
+ {10883944418224886092, 9908329441525486205, 11238684990962507809, 12900626758810151662},
+ },
+ {
+ {2629393050548942288, 6363222898077806203, 18404650886731368903, 2691451856029551156},
+ {5104932743043229112, 1302939624985069019, 11820239270922660661, 16228045717328023331},
+ },
+ {
+ {778457530134061801, 4290661013056586404, 12033745869654330486, 17833837257536520292},
+ {950548111600899172, 16026254932420015523, 14620989142158250051, 8236598933984161995},
+ },
+ {
+ {8828068000936861634, 10901971915827198521, 15635295283164640480, 352740455954411610},
+ {4853015383138960329, 2945696874639059776, 7204307993540375148, 11980890732241054979},
+ },
+ {
+ {4077800412543228484, 7173833470188867493, 4604439809988262876, 8090706047559948234},
+ {6117166546062912279, 15748537214854486946, 16719594636199001564, 563850925691991999},
+ },
+ {
+ {4802884399593912281, 13437020732272033050, 12197788481695720547, 2162699662292229581},
+ {4193517889478995518, 8610646873096992408, 9485787089338760040, 12392145097158647056},
+ },
+ {
+ {18079795516810465755, 15723042000668265475, 12488322519570427659, 14012836221417650412},
+ {6534900133691249330, 8115921632235353076, 4093907116172233459, 16784728000548766561},
+ },
+ {
+ {6262200118048820167, 12719453838344002789, 5526427573572313315, 8520226123932607126},
+ {3618116539863181413, 14020033065434801713, 15675496263723836857, 11987954535452978647},
+ },
+ },
+ {
+ {
+ {10847249691051757241, 13332329214721571156, 12457628412284474075, 17044657510482764070},
+ {5218221397478351943, 6922630493693541156, 6207927102810766143, 5644846665334649748},
+ },
+ {
+ {6506371904134856034, 9541373683805144018, 3149037850125132851, 7111810601994573897},
+ {16732445693192247884, 4994069681898274622, 7223719243730104348, 5649174084086150712},
+ },
+ {
+ {16562962997045986629, 1977585352264948582, 15588655103333244279, 253344970359156714},
+ {12939363813291366775, 12548224526376199974, 14450582788883748364, 5869541533939881460},
+ },
+ {
+ {13970586842647892965, 3680317572634289692, 3416494470839852757, 8341497967750607131},
+ {5522860734580749818, 6847292760525096386, 9317394708872196559, 8522252330730808934},
+ },
+ {
+ {6838341670149165895, 12326189699069923388, 9258908232339348843, 17297038041466207989},
+ {5242182985453021593, 9648294165629935142, 9715128265517308395, 2662662536493743894},
+ },
+ {
+ {6790869670806738567, 4499989093713728199, 17496748050437205626, 7194829324969293638},
+ {18432532588985091708, 12041300075343806904, 7788543067151959941, 13703334460383638224},
+ },
+ {
+ {5996381448168274884, 8108757135223610234, 8067369725584584297, 7184925262427750366},
+ {8199341143188441284, 13031376443169557016, 16036606349050125404, 11958720833222295864},
+ },
+ {
+ {9293668142017263584, 17134656749295164870, 5879480323258506465, 4788695233340705697},
+ {17809277710857366810, 15157733645094688870, 14143869691462709080, 3162286338158090229},
+ },
+ {
+ {16056959590901591813, 1082823161154599460, 10221040439441372421, 18283403891485112294},
+ {17582486701671091218, 6489397700174053547, 3952499348250646760, 4381145145005361247},
+ },
+ {
+ {464321249842430028, 11444362575253049653, 2734975360475017776, 4746579078625212558},
+ {11326126526565916100, 7840007639237722362, 7545779893877671555, 8952053274372957788},
+ },
+ {
+ {9171324502111757965, 11245577625425383295, 15294815109909975990, 12306264653913762086},
+ {5906268309303228662, 2685370982867857233, 5470203265560800284, 1354105134944127233},
+ },
+ {
+ {10610818607308010986, 1017341076592473937, 13259969743043862138, 1850907007366751943},
+ {7689302552902672401, 15375957693502270090, 13877050204486881614, 16441247744335371320},
+ },
+ {
+ {18161720198110725057, 14887135440336057963, 6790952723850964648, 15120775513153544155},
+ {11797493458812299470, 9090758778610315656, 605835259544633945, 14755333155432393992},
+ },
+ {
+ {14967102006962978091, 4301508725220174920, 11299977101982031802, 14410789725331022027},
+ {17005709003661351591, 9843840931527318478, 11917612896070173894, 12007179364072802553},
+ },
+ {
+ {15913542135925395264, 2830138374220921671, 6395020779026969444, 1239443258852925290},
+ {4519359001030231260, 9606729174209623750, 14291346135557028396, 16179513817501558495},
+ },
+ },
+ {
+ {
+ {10223936123327786454, 2321887803300626936, 13607747528117965743, 10456421630388400123},
+ {3266519591187534953, 1053691207967834494, 7151443045753788549, 18124688636664828399},
+ },
+ {
+ {6946488664257064464, 9775328903143754150, 58700362449753229, 7901817271072273406},
+ {5074738678159003249, 18397239731906005785, 15911102965988125888, 9277654580204145348},
+ },
+ {
+ {1874700306906525099, 7337351570334852732, 7954195906114335343, 17230226427261850070},
+ {5181329498860909261, 107167242193237170, 4364856176182710332, 14611171841443342914},
+ },
+ {
+ {10990327814895720476, 16588412771027628390, 2850177278998422188, 11569813740328484871},
+ {3922148781422941186, 3581659216490446242, 3646872304052351376, 10887870617200051198},
+ },
+ {
+ {8175121141368087217, 15079393830876652065, 16766987879267543828, 10582796406546815217},
+ {16832256009371376870, 10042650470778064892, 17867163453935683780, 7123418345572641116},
+ },
+ {
+ {1782651072016504775, 11033882508408412333, 11105300284232190625, 3276372405089292929},
+ {6399472468041061588, 15319690780388315076, 4928530863063375966, 11596222198340277418},
+ },
+ {
+ {5452424185619067445, 12050433097586021281, 15018766900844679217, 273234254926088220},
+ {15426383635547379531, 5213762666043737626, 2829185842069118470, 3230799283770935127},
+ },
+ {
+ {280030342772428106, 17354882606189694746, 17455445295460080284, 18076709382926018941},
+ {9895982528034548913, 13681172423928175330, 1656433131309057012, 11935757350437721114},
+ },
+ {
+ {14437472586336929440, 17387041914242263390, 14861577074379746687, 5146556788377906297},
+ {13036814755814090195, 15108836859245573802, 1667563994642521213, 14722845469958372258},
+ },
+ {
+ {7781061995240980266, 2066078418484154391, 4089376589847114892, 2434843609506038666},
+ {18376509832460312721, 7187709121160627756, 2455436656049651823, 14419116837518875372},
+ },
+ {
+ {1270185079976403265, 9214436628411717184, 15450450827683432913, 2880014804806096082},
+ {15448799931519826757, 10080240282127928735, 10673974088219619287, 12998944469117087518},
+ },
+ {
+ {18028691745165748687, 8931519595829275195, 18379893031942930865, 12120980098075498008},
+ {9596371470855895261, 4133427878071274570, 13159312399982591699, 1639865074052258019},
+ },
+ {
+ {1661696187746428348, 2656198437014978712, 13769477291975851694, 12512848714492869444},
+ {5980926616932344693, 15821983893144953005, 5816015630031200526, 15887565799959254415},
+ },
+ {
+ {16463929919291729278, 14920112063826664828, 10056471508435050704, 10696267144984026763},
+ {12049530292963090991, 11926086636123189182, 9464890378472966538, 9719194510330239601},
+ },
+ {
+ {18110249193861022779, 5612784685592189906, 11360454032996393150, 6795401682138043705},
+ {1961398978248902107, 8999847457729547905, 8941741619641401180, 6086938661427918241},
+ },
+ },
+ {
+ {
+ {1119490156854665483, 16772836556735128526, 8607715508817325509, 9931017263385440911},
+ {8799481055779587022, 11740562709785257943, 1956849872282864970, 595288629437737005},
+ },
+ {
+ {11601570184515356415, 11247678357869162156, 8415095559389686315, 9625816053586466047},
+ {11807876143163335372, 15690209134241397733, 8684637224468015605, 15974968144193406020},
+ },
+ {
+ {6498861108824484382, 4670555282769381189, 6606014320886832914, 17078765892830617318},
+ {546267528591230105, 17808649363082080722, 3219358059129920687, 9180845247506322192},
+ },
+ {
+ {11275984449259340674, 14922638629881602958, 17186426309348732477, 2094500549052461127},
+ {1245672419927595636, 7529921141299797945, 3181089597449057707, 7749529014968942143},
+ },
+ {
+ {11277133910568934671, 4278895672933635880, 5062049475469993812, 2827897582327968966},
+ {2992831031801695571, 13244636528396736375, 11509629662092358067, 9385849226639579800},
+ },
+ {
+ {8454236707620433029, 10192313737667573051, 18232259474515025711, 6196538652828521245},
+ {6326999652188467228, 7611130140249634596, 5729331023083628955, 9386297316005425714},
+ },
+ {
+ {7621274909358193632, 3619625095597194913, 18038386254997645285, 17262892689028255302},
+ {17953989125460428814, 4571031913557658215, 12218524221515562809, 12016327352942264220},
+ },
+ {
+ {12842581296013847382, 7845624487558348664, 8747439372999364825, 849305823897878133},
+ {2217292264321907974, 8173534404179332054, 3588643190593022889, 12047811416592660080},
+ },
+ {
+ {8121746263843271081, 10363835147942471345, 312023379108980148, 17191823034761670562},
+ {315776409136454719, 8322002171533871918, 659256727451485128, 6073539214057006838},
+ },
+ {
+ {5999134638957620752, 14196265207258829507, 5400793612736232063, 16259338359738368573},
+ {11179852704740695306, 3486799782309774463, 3060529319750906379, 3540275797284687957},
+ },
+ {
+ {5485176043812882513, 10727553589889164848, 5617457077214333092, 15937493816713568462},
+ {6287330459840726949, 5451240171054977850, 3524414944972920777, 8740440597273129486},
+ },
+ {
+ {6959527445237219799, 17170778245769606301, 807762173031474321, 9151445233487017286},
+ {15103411489939446333, 7976669669591851659, 14824323986579638641, 1535817133122800221},
+ },
+ {
+ {13993486080187419934, 14882121651768660644, 7947881871819932407, 1364312030151957949},
+ {10673187305202558690, 15038997055055408315, 9268330880459316485, 4319340556575124142},
+ },
+ {
+ {12846922591360496097, 15518450931549829779, 3843880753372237176, 11741559986398913430},
+ {16974382348775305594, 7085384294841794242, 10278478682851578175, 16997904984485898637},
+ },
+ {
+ {13670930062027115328, 9912297966339314023, 17061419147322177635, 6220676237879734303},
+ {12723388668517709225, 14967294924815531226, 7286002704046609276, 2105494380036834916},
+ },
+ },
+ {
+ {
+ {17955247196574331290, 285928599571507431, 11902987704297070981, 2841167725097799100},
+ {9281167410796848363, 16444340476026142274, 3423202423051178709, 9101021305726472246},
+ },
+ {
+ {8869273893561412239, 10349812081309865197, 8913824872487209090, 3148808685596180274},
+ {530908416884501807, 10284103744075805979, 13606889938905754722, 2418062398586758364},
+ },
+ {
+ {2298603653884322501, 601221199968240092, 1285112712738261659, 13882709760355308533},
+ {13563254433762438170, 13447718334658435053, 13493687958886238103, 11032778298151679283},
+ },
+ {
+ {8626760324117733843, 16403951745962159364, 5837394731212322914, 6847167719031297053},
+ {2888142337636247281, 3409818743436360750, 1677113113408664401, 1222157560539217476},
+ },
+ {
+ {2294668553308381923, 17165287249067859297, 9897724011823072967, 17409851874231284314},
+ {13888575318617508639, 12092766090379658603, 8412268183255186961, 8046572777745318483},
+ },
+ {
+ {13178439025428734594, 16388038968589028071, 16165750006742628176, 17903639397633243161},
+ {9560319088110737392, 7888974492854359310, 16116323630343158496, 10177829649622711030},
+ },
+ {
+ {2378363646789710539, 494954399989334038, 6915496914984330558, 757197055392642378},
+ {9097171378505823650, 12104288338329241488, 1905673690814481722, 13011078677095066032},
+ },
+ {
+ {12712274459771886808, 15748114764509451764, 1994630377849062253, 564390855806287868},
+ {135493276425567450, 4305883520257541088, 4842008929542073044, 7035106970720249617},
+ },
+ {
+ {4772079965696324995, 15925041062593990538, 2818172089014580505, 11304215074611546986},
+ {10130691823118346040, 11796228810049908587, 9262801389703476249, 6629344122525229781},
+ },
+ {
+ {11045983914861167112, 14106148195606833916, 4442596873181225087, 15627975325288846806},
+ {8173496855557146242, 6061080385918934423, 5233260187121969538, 17554093556474728494},
+ },
+ {
+ {12122792368758575262, 810814789452398299, 6387727669765211854, 3304731719391402237},
+ {15296845834923103160, 3685348582131767195, 12636335057478947340, 16971253767099552987},
+ },
+ {
+ {12345454807632743424, 11546569651702761483, 8873100774001529421, 7001975923028025552},
+ {8129283832066039281, 18147888225504425296, 3510907297028745651, 897602195837260824},
+ },
+ {
+ {17896345382362222994, 2167374959533815311, 5029128091600127895, 1770543276160593316},
+ {17234124146043512942, 5338191548265818047, 15676046602975694398, 1943153641089805200},
+ },
+ {
+ {11084819495273800718, 12966507689731825252, 15026437832429189138, 2506312683689776139},
+ {7417463323869895004, 9819555221238697390, 1250200244896601539, 1394555910521460172},
+ },
+ {
+ {2221512141494043286, 9203854585477888176, 12171379127551511504, 10667358469120985695},
+ {3795093165005123272, 6129005969593025264, 8738204659003189419, 5273583671698415302},
+ },
+ },
+ {
+ {
+ {16549155412115374305, 75977962737081600, 8870825488941031605, 7403557657089993256},
+ {5825394234709429518, 11978746413791918409, 1876293130790608838, 9416631623519692610},
+ },
+ {
+ {12346821858361333862, 6352722970730511156, 9920942104315084988, 10492373916708072181},
+ {11163323626947992791, 17035282992056675772, 835685192553490421, 12792459312570503983},
+ },
+ {
+ {10447922451077327640, 1515090998837129975, 13498807582085718212, 1212623301098019779},
+ {11573518650162536086, 4823461685803772444, 7289704908733783271, 13167881392748327839},
+ },
+ {
+ {16959954449957105311, 11051594981465026138, 16062472412226411858, 1976004115345602080},
+ {3630495248560019222, 12698191555196404138, 10107923614229901155, 1597725222698864118},
+ },
+ {
+ {3416019089997140849, 3011417601086561495, 6275242351124667286, 14197557183081060761},
+ {5633711018871057458, 9723496411345030748, 13910057756335530832, 7285051335492395815},
+ },
+ {
+ {16774605620279328247, 10223834398868957807, 15781733027568799739, 2607095622729296315},
+ {16499590296954181006, 7576646116121533069, 16638313875339315529, 14296194207652471696},
+ },
+ {
+ {12874411821611501068, 1998417862388106640, 13882642435422318946, 5791129521978463837},
+ {7512934139125398199, 6966283273373526248, 5475728301311080129, 13542211842758381589},
+ },
+ {
+ {7798993150530415596, 3288770257171840452, 13373286069558329631, 9784279046496345014},
+ {15725032660238528813, 16038931923358478835, 6921788930154218900, 6093507035435214187},
+ },
+ {
+ {12194839527972802101, 8376199250979271449, 9055995864116790217, 8125030124567662718},
+ {1070812422878398727, 3950906148308170707, 10121516919638719072, 813471384549762068},
+ },
+ {
+ {7610605259962047827, 14617655900985224117, 16089669078196617440, 10594009761533811214},
+ {3425971360520359121, 1245021768718221594, 16690372892586114152, 9933179766195044175},
+ },
+ {
+ {15142732720676276463, 17435583143726694663, 6030257647680338377, 243683009289621849},
+ {3064238900429394982, 7655019927497549159, 4484400084400458429, 11650860345018651068},
+ },
+ {
+ {16203650576183697977, 17614744533772112337, 1119292890050870301, 4574885263986729787},
+ {8108207498737924504, 9708434439316056191, 10676823369888368482, 1078311554675991883},
+ },
+ {
+ {6876202174636220158, 18057502510666060150, 7821730895845187783, 8882321799602877790},
+ {16220624224336230256, 15562800387021280583, 3043825293109091520, 697130162105054983},
+ },
+ {
+ {5394549491776704087, 14795348078061113966, 14206080764200897220, 4623073019242398493},
+ {5850602047109930316, 13783531993760979209, 14764346975698048641, 8951680172224205890},
+ },
+ {
+ {7302725075484262769, 12572584665857403749, 6499691362933905099, 14476353114356185371},
+ {7381716148644532401, 1573798302334388880, 8128390307766282880, 14547454176248589604},
+ },
+ },
+ {
+ {
+ {4477325369345373420, 299141931133875776, 6787652129916359301, 2498016036564260464},
+ {13342319943892943548, 11124287719737492205, 2456333599771808442, 5084719026388755304},
+ },
+ {
+ {12246932755942887931, 10842213418139067847, 1827392608284960926, 6961756951208563550},
+ {14626966634382828071, 12653808277900379805, 3359368990539585596, 1190255644328095727},
+ },
+ {
+ {14845756090430871381, 1260135108359348096, 18373249503604334230, 14931345532671487262},
+ {8304897926217252744, 16639705302116302354, 14578633917159176703, 5624357498623418462},
+ },
+ {
+ {10836955050615624183, 6228108794259714192, 3769609579318360527, 1481673673659326756},
+ {301329772189110029, 3574710782304999603, 3037244905687722509, 14442941761397229485},
+ },
+ {
+ {3863379967423475252, 4598414140150397553, 13498347034161095546, 5995458763090398343},
+ {8994138995797612256, 1053878477247308872, 16525881906724873538, 16597989933510424042},
+ },
+ {
+ {18195618552940791509, 12801347400921689158, 13372055618013067129, 14929951832730936581},
+ {2563109394536979589, 3392102243539970867, 2978145866937578695, 15809561751101461921},
+ },
+ {
+ {6470844231261685519, 4860920111547376221, 6133864928365904793, 8914566156785557227},
+ {8258394874597607714, 4464810914649217913, 120457844518757378, 18209291810039348360},
+ },
+ {
+ {7739110373965523311, 11019153332996240080, 7346010155518751797, 14853737521111213548},
+ {2542883237207113209, 11015136828834421504, 1998601666328316353, 1540417751495800469},
+ },
+ {
+ {3376092179741497360, 12221254335784366861, 5282973200516004163, 11372960528472533628},
+ {8188139842572259074, 3946305224334575645, 16643338862665650950, 5859492058050333909},
+ },
+ {
+ {14916042081488114271, 3303190861468284762, 14234546272335492538, 5776190344932209905},
+ {16339988209459724195, 10022514953301624769, 7878363685856556300, 3127365206552843780},
+ },
+ {
+ {8340102858481562978, 5401806343794775245, 12619159636229742566, 16221085737347795155},
+ {1241298364136442056, 9142635103215118982, 14403222699038355211, 12145678822325215894},
+ },
+ {
+ {599034134015360884, 11263317530774995092, 6667501365379084069, 9844276013103312691},
+ {7566306886180438990, 13702768345615509363, 12525031963170717968, 8463786212988210464},
+ },
+ {
+ {7279390679700007004, 10579602100702377479, 4366146547587324748, 6962092370680728424},
+ {16372420580520124739, 4597019194685908384, 13217149760366044828, 7222487257194391332},
+ },
+ {
+ {8454830421421057736, 4100731209937375984, 18348214289895908213, 6778376865226169852},
+ {12945227893790929647, 1818657910008686277, 3629900123705314093, 2861658388952811590},
+ },
+ {
+ {15882969890737930334, 5849157078791136995, 10068103243390577755, 13131421240079433547},
+ {10404642120419399290, 8199866428750316037, 1032443962738597455, 15582122438927179496},
+ },
+ },
+ {
+ {
+ {6390361653475754940, 1093882175267357438, 3784079074949811167, 17343872969822169769},
+ {3359715652121662979, 16808529787251986583, 5169730697018536870, 52766949850965558},
+ },
+ {
+ {13147212495082910072, 5628914243538540648, 439989514095330941, 7620472329041817834},
+ {4272251824771633288, 16564977601507013119, 5441117136715882317, 5622571730905974389},
+ },
+ {
+ {4207421531032215145, 7924589143024019458, 5496622772676523695, 7061817399179278712},
+ {7371689806847905735, 8282663810521090335, 11422487361383982601, 6397294642072086677},
+ },
+ {
+ {960381383357168877, 16774709963697143275, 17896181076874992240, 1150415168189819777},
+ {5498481130530161530, 6895900060791069290, 2079514944189747822, 3428689507902936354},
+ },
+ {
+ {12056920178557394302, 5131253251712581899, 16251877995882633963, 10883064494054484051},
+ {9473274815269607947, 8874308005470196739, 4412709653190846630, 16469366225886156991},
+ },
+ {
+ {3547198835521135552, 9940690805769919242, 15170549880149605690, 10701681269101530298},
+ {5914809102954412895, 15790219349994701461, 13664049285300230863, 5735249081148743651},
+ },
+ {
+ {14753645881295168970, 9410794713982813264, 13485977523338061503, 14267793994973767571},
+ {15813187206361118954, 16449603969001878152, 17705410933007144731, 10960511750491378082},
+ },
+ {
+ {4669722990542640772, 10017368027073540045, 13392819319228640800, 1070815632453829996},
+ {7274130058405640448, 4460835865761538026, 15283885107956150892, 5815884817303156137},
+ },
+ {
+ {3469614802230980914, 18060080625283048965, 580464295809221798, 3338153928139206412},
+ {9845192339392693455, 13250323899168115720, 11058696855422647818, 9665232062806155902},
+ },
+ {
+ {14461336556325939926, 16946363864290460645, 17546878353664479567, 17949437676666656135},
+ {7932367178689988878, 4806368097560008659, 3460529608269790679, 6065321700046177254},
+ },
+ {
+ {16883816924971606835, 5486714189826473375, 15204267662844332028, 17199232837602035696},
+ {15958749676770074119, 5540664038667498053, 15914281753951743318, 12225053486711127081},
+ },
+ {
+ {15346266095840263783, 14129675453960658911, 1781465630073142581, 12398710533895277470},
+ {17697074063253841985, 13826156613321578228, 8855030685964401164, 3749659313217692983},
+ },
+ {
+ {14888039192306165275, 11233459160096048886, 709252573146299872, 17614748022803380926},
+ {10853790173866038588, 2988411430602910678, 1343284586410250367, 4491892393582674365},
+ },
+ {
+ {5653853395031137185, 11847098886335071270, 15046954358935848863, 490763079643421287},
+ {3113500211585712650, 15997550469331041114, 5281575885072775975, 2887311255648554506},
+ },
+ {
+ {5376335754670737023, 13164671289498247151, 6846569847526260467, 5496656304894178122},
+ {2009132493403453913, 17250524577747091030, 2315376314333653245, 142024984008484689},
+ },
+ },
+ {
+ {
+ {7237168574323016859, 17908810107504968137, 16225708127838178121, 11127095986977103648},
+ {9346291308317410251, 7381283458277047010, 15168602815371846943, 9193719743691734294},
+ },
+ {
+ {9607254959726458411, 16837156817186931862, 16178143308706847393, 10970721795101931539},
+ {10840376278605273092, 8298765077094727469, 15520543037910966843, 11484620381947762562},
+ },
+ {
+ {17395070963094117711, 7608132718922490881, 6531178971071758016, 1302814667007331361},
+ {4002629363862769670, 14649492495298089937, 6868174210142585697, 15456170652716048683},
+ },
+ {
+ {3688308493559609536, 5123828159813683938, 6245436817220183971, 13062234263274605325},
+ {1313395302496832996, 4961840797708687855, 4990192311341859196, 5283131006216350959},
+ },
+ {
+ {16952735659396950704, 1249482796824289329, 17859504101404809981, 13260403650830168625},
+ {1583343855370236084, 11389120333403185826, 13676599385745755008, 5066667130137739346},
+ },
+ {
+ {4799264864906918301, 18347145714884655971, 17034125441088681346, 11828378178487279470},
+ {1759038296522081901, 9582407833575609381, 4195817009050503354, 12618256395967210055},
+ },
+ {
+ {6486755100213398364, 5270923715575268322, 9268255346880651103, 3147724493117082267},
+ {16710318779269985633, 1240462642985509644, 2400811796254219369, 13670743068809614358},
+ },
+ {
+ {11437779990773246594, 13609113239383378152, 31268927496646090, 11618772705165035208},
+ {3078024460365036167, 12138983306908962712, 4779157919015181380, 11901698850260672002},
+ },
+ {
+ {14642787507945832432, 16258081639927585935, 2560321462542164242, 16286882196975458174},
+ {4328159372518768969, 14313553865397841147, 13769372656320240568, 8950675126435331579},
+ },
+ {
+ {1309709344837422378, 18403288028608342631, 17102350491414677993, 1133523394849437315},
+ {12526496222782003755, 5447309058259018864, 17311120581405946631, 3760058661125144368},
+ },
+ {
+ {17891474172606596407, 320094264574086461, 93927075222964142, 14355817838636249140},
+ {1777882427773785068, 8237021421587560510, 11520559469641852991, 10567910693910023157},
+ },
+ {
+ {9164300764173563614, 12322279811717869943, 2768902015676238485, 7761799112151133995},
+ {5740162933856370894, 8043946608495226840, 8923704438836381869, 15189322655373943849},
+ },
+ {
+ {12046275966378825708, 5909386969214935556, 1201990704907881028, 12128549009950617306},
+ {10773478878317625320, 4554854625564648958, 14029736945871573056, 1353247251064221090},
+ },
+ {
+ {11909123603272307101, 5517949035179831783, 3295386484950432959, 5605137795524476293},
+ {10718654547602473221, 4984952409581272095, 883267724006996723, 17328431094026829348},
+ },
+ {
+ {13671210467347025770, 9980617617519781731, 8339868735163579231, 2150724314757661915},
+ {8571153021065445899, 9146903697769397191, 9122246102814640373, 7744779513085605450},
+ },
+ },
+ {
+ {
+ {9508384588323002196, 4786531415304518048, 2690306308552249535, 12208815515689370850},
+ {5145548243685871201, 1536915039528215765, 709289946127949333, 7152734178531880864},
+ },
+ {
+ {9627905753364576437, 12776456422166281355, 2851899644189834214, 16998174196920379994},
+ {9001602524188761177, 8960294999163663712, 6580949973363012183, 7568306074815116797},
+ },
+ {
+ {7686633626025788546, 8110394872630496906, 8482210436161892079, 16882855163559885891},
+ {1154081680627148904, 12804224766760790394, 1850455828762691082, 14191115350906359627},
+ },
+ {
+ {13345381996769253014, 6278048669175242345, 15990349685835870151, 16358261962292186792},
+ {8505261070637963021, 9396725065098564446, 15331953351049782155, 16194796339208321205},
+ },
+ {
+ {15505898598362934929, 16825210854979603981, 4697782190623959274, 9370503401456774242},
+ {12874840227707962403, 6119547445810629810, 9764164009057494220, 5416853666956021065},
+ },
+ {
+ {7699498684510298360, 16542285627069734869, 200751785530104649, 6985944962584804095},
+ {7365545959109847649, 14865387755379324112, 4167319688751668987, 12162483513847343974},
+ },
+ {
+ {1039980316046001816, 7207503221801597145, 10591680158322288825, 11266400320575557454},
+ {10706275395641440317, 9288394947884616208, 10167533985006762418, 1456585988309878747},
+ },
+ {
+ {7076257175157660597, 13221730879315432464, 4499548735964119085, 7559253754663705944},
+ {10196808438730350168, 2391718471837563931, 914409564589897387, 6649744842278078706},
+ },
+ {
+ {10039057354622246685, 7195562849416781100, 17696866082062058984, 3668253949076972503},
+ {3291647709604288622, 14581068695089559804, 10104544037456163379, 5446494334499941155},
+ },
+ {
+ {11083442423555675697, 16463352501129765262, 8326106600927169880, 14461723217830443766},
+ {8960039240507947123, 6112452535158412156, 16298251376476091126, 5185774007776019173},
+ },
+ {
+ {5801222283949474418, 13946418525037992779, 2275515160040674505, 3244981365190546382},
+ {9460698310301428534, 14807942233170768102, 6180104492182570514, 4695926909096500015},
+ },
+ {
+ {5502356275170104522, 12750322860129485966, 9581277511584938955, 3872282844937972630},
+ {13668854758739140874, 15020438121087800965, 4581631138384430657, 13296613956093963588},
+ },
+ {
+ {7394309355461523862, 5374161350639568117, 2763783634295242959, 10215168014269656712},
+ {10862202275249464165, 16813773246956503013, 4644566761082532589, 15300517379307655907},
+ },
+ {
+ {10894319502247195436, 16018449015752583379, 7936971022695592164, 8273950599391165937},
+ {1130484969598457981, 10652972605389048300, 5964985167476071140, 1178111465674979168},
+ },
+ {
+ {3215460690308212256, 13044009109542950831, 1248575312568743704, 5805472854961471970},
+ {16935262056111009166, 14323719510498371522, 4137201278518680629, 9262447671880633672},
+ },
+ },
+ {
+ {
+ {10228366644420455452, 12084265406352277347, 10265869676493821892, 3560143954870272139},
+ {14368775225608592689, 13173522067191372913, 3592475039513249949, 11243554718624931135},
+ },
+ {
+ {6543255501112359319, 6063422531520498671, 17228726254778244409, 7570754775709645369},
+ {18222396492501523182, 14903937974816691813, 1216646642383641441, 7602781158453005929},
+ },
+ {
+ {14568782576170814716, 17582848432122737506, 1079387064102681806, 17278567874821675408},
+ {3094302191119669899, 3730448048895347901, 3508894590334961422, 14091660942919228106},
+ },
+ {
+ {13329033749048978810, 4765695903433858377, 4452680451529163940, 5638854187414651620},
+ {7897503022043776206, 17187635538005569019, 17766753195497526986, 13201529234556380285},
+ },
+ {
+ {8934119620399766972, 4226481091885914732, 16000709195004445297, 14687868180928846933},
+ {16269913392757896907, 18294005838441325342, 17625669613551023126, 10864307042201644469},
+ },
+ {
+ {14722530431277419104, 12333728409662476827, 4162946257347548625, 7052045338975163666},
+ {16435875989376103923, 527141841571514699, 8480360258792897962, 4322786951393806781},
+ },
+ {
+ {14380803034817149259, 11042134597430846555, 9992762805140200547, 9895143575678511242},
+ {3228768306004664915, 16153114680219541243, 12036181641761325912, 491369524302296324},
+ },
+ {
+ {12320933424684960076, 8906954611339502145, 16931708732547376267, 6446897311644431583},
+ {13749563256713530203, 11522599770043814384, 14455556215959342791, 9022955938835504923},
+ },
+ {
+ {8738648866901281761, 4688741093801776285, 17069682640810525423, 7158141773766072053},
+ {11460933790638879246, 687134766504463570, 7796313120876518884, 11150451731319135164},
+ },
+ {
+ {13652684811535265600, 8494726433844453583, 15999979552047212740, 16433235792902853942},
+ {13641303900302396790, 418630713805776951, 13090797093697365883, 6529658430803752768},
+ },
+ {
+ {3944614182924380177, 9542495129087581473, 6699683662731923419, 5017219913619823514},
+ {17045736494588140273, 3578045824537114332, 15234910011456151711, 4392310298224006475},
+ },
+ {
+ {13050963220563520130, 16311879939705207639, 12461297624582251388, 9677731599265769222},
+ {5160679975931966230, 3218707041599533629, 17098083534384492023, 2330141721984719029},
+ },
+ {
+ {8245975647138927146, 11496799090887525271, 1709462103065191917, 18401529677683893204},
+ {13971543411749700717, 15107687167816783802, 7171906080161032790, 2549191081579169610},
+ },
+ {
+ {17251496610557148115, 13056982918233222110, 16321077587645226911, 15873643227887663856},
+ {7790198561388957118, 9539520576306975575, 15234893276112958324, 12999697377068360422},
+ },
+ {
+ {16169560456946825943, 18091964243071526492, 4341876361632902705, 7532668331381251135},
+ {15346381760818990405, 18301333564088079147, 6565096728885044125, 2494845330727350075},
+ },
+ },
+ {
+ {
+ {16319476863352440541, 10283930715856640343, 17675054544532098447, 11261132162985242084},
+ {13712716897981761400, 2681907143459288706, 6930256922080133347, 1445069157579547822},
+ },
+ {
+ {16928574868467385886, 166417019993787654, 5882811520342817815, 14106304179344008065},
+ {3747123724781081800, 197109533566874475, 14303280595714789450, 15457633026018307066},
+ },
+ {
+ {10773597511592584859, 12552868588431074640, 13500771767160426835, 8002499270056378440},
+ {13792839099998553174, 12949371255843262119, 1713974340992291550, 16150173130483658061},
+ },
+ {
+ {14745984256428057001, 9333707338036985191, 15365925315303462, 11789129028059619744},
+ {7873100217437235208, 5289763977161829145, 17731215200358323788, 8876377479309635703},
+ },
+ {
+ {265950821974454804, 5047467530470542278, 17523044368516619801, 10054436503372765176},
+ {10321185867287373431, 1212061937729015591, 15311258419138633926, 11236518538207084768},
+ },
+ {
+ {10904693956407098222, 9013418755007070130, 15510005599846320670, 995378633446250700},
+ {12234095025518917836, 6689106237771514188, 2809193993744369126, 548124799387888260},
+ },
+ {
+ {267350765778774337, 2853877351938464055, 3677119082593358544, 7685335121077514739},
+ {6491980094762370981, 1384870316654548002, 10568872345228996498, 241629538659623878},
+ },
+ {
+ {5839400175629113441, 5238299193248381245, 16787876416022887315, 6051613843621920008},
+ {9219569873668974552, 5916753090530931032, 13390630214643423749, 3265335490455191268},
+ },
+ {
+ {1507475744849985303, 2597075068965622770, 14968669113917266926, 597606442423659891},
+ {44293923912414886, 3832651144752540816, 17438860065613195810, 782112340603343331},
+ },
+ {
+ {9050896199196733903, 6427608033444590004, 13787696679536621857, 9682087046920409188},
+ {4519093754155995429, 13564098392055667371, 10512507082236058799, 5289934424008191746},
+ },
+ {
+ {3477191607403300916, 18283244229745029067, 8462159792484018099, 3056576498976014760},
+ {7259283167233712785, 12530251965039903998, 10232104933720625111, 14190745998092156987},
+ },
+ {
+ {15759362035410895911, 16075598437961371531, 4651513528876405575, 7694151626503869614},
+ {14468862724637972284, 1838601521755586245, 4168957446435305706, 8694905613027663664},
+ },
+ {
+ {14825552838983151434, 8639609968952840931, 15547914584352392016, 2313507499500708287},
+ {6902543375698033684, 9987468886016348918, 9068175779860656258, 6899641689193116297},
+ },
+ {
+ {7449110402827616954, 5689206471789540768, 12722069021950813669, 16017131401246233663},
+ {2240977975275954837, 4794705713606614946, 5734937900461809607, 118285984764445639},
+ },
+ {
+ {13917685647531721740, 2432096911145792817, 17733637484624159521, 3848601825403209903},
+ {8192433211051054683, 17388066421914150767, 14336306308847565282, 7501625553608785022},
+ },
+ },
+ {
+ {
+ {9194523390605857831, 2335161171394626054, 12290490336543843159, 12464172604156286188},
+ {15842196578033029974, 9081285134201585379, 6123406461662038242, 5504260508195082396},
+ },
+ {
+ {9599159247384506427, 13011559959971256245, 6331802547989957841, 2642320882309956905},
+ {9140255367820630480, 6883541786494880896, 9560822438260750771, 9273862677291701694},
+ },
+ {
+ {12578940088863451089, 4698579870843180556, 13634180401794570924, 15763130743395284022},
+ {7444441842547931942, 4944622454458561492, 9589156490791486440, 14762328488235724618},
+ },
+ {
+ {6185067974942684922, 6452325785873503452, 15247257292915812252, 3689324664200339196},
+ {3264129576054154137, 14977721630214750038, 10720913377937894256, 15914487080763816378},
+ },
+ {
+ {8926126498606164569, 12956394005759769716, 16902149488499586013, 7841840983349613625},
+ {10587053251468526108, 696362153501209498, 9784750880259098186, 1207696323194229080},
+ },
+ {
+ {6366297849225708271, 1653728037493780302, 924103820671018926, 2050213326049184692},
+ {5527413390519421127, 129805527414320490, 11550889572378802302, 15667992622431666977},
+ },
+ {
+ {3759028419971240833, 201899490644698259, 16787882148977818573, 3755266958958128460},
+ {16997526157701685291, 6920710029293447897, 14077301651040071328, 10880144992445166875},
+ },
+ {
+ {5498621600689515064, 11498885804037952971, 12697073118321478539, 13999008478737234463},
+ {4324885099420360642, 14021182496192299466, 10763088992583373843, 12898585157666243299},
+ },
+ {
+ {9367059860785010847, 15787147891143727655, 2519720658767337732, 11593809545681651942},
+ {11966083811953753216, 12761111316475086277, 5681625861426437827, 15920587591610358813},
+ },
+ {
+ {390729441391219522, 16780558466241830343, 1374488446906327562, 10865131913700232628},
+ {10115076211715532468, 18184016780675566832, 8365356477197603014, 672096097598251136},
+ },
+ {
+ {2393424067712509928, 16879911507754196299, 6441307574161100589, 2818743579517374412},
+ {7083174841445248189, 3410683030590349702, 14697584027599531676, 8328975445543175696},
+ },
+ {
+ {11622402383521841588, 18271726976204770291, 4805501248621435402, 13483122453682180759},
+ {9288143526654965614, 4688427612851085031, 3280806057528512375, 2249349779106893174},
+ },
+ {
+ {6807440366000180651, 16399452121226315247, 5098169947999459087, 3558234272787006753},
+ {1792969085845015294, 5524357634740353242, 9429244535996516945, 3937357214017147760},
+ },
+ {
+ {15504868609044485967, 6752328153557303622, 3778610801922734369, 13830970685441980645},
+ {8715733351182855585, 13970559751738714496, 11410776131378170826, 5487441016062951646},
+ },
+ {
+ {13162254303511925286, 1500183854026947752, 6344593292969383689, 13968537166293685529},
+ {3100593991852309751, 464141462036312207, 5107705843278430088, 1965835506583809167},
+ },
+ },
+ {
+ {
+ {12081034000518110752, 2773740877021737013, 6429475399936543899, 6804412599792308979},
+ {16082860502313571182, 10013838454082912732, 7176778953927883654, 8065751639278576331},
+ },
+ {
+ {17741525051518363144, 1374267330336191942, 4677891169679898540, 9639823611685431337},
+ {5482431056894095950, 6629146695374718376, 3884574854221819712, 13266790928096813258},
+ },
+ {
+ {17505459029376928465, 14087658194607915364, 12240552390931686885, 1809009366037859941},
+ {9468395484396723291, 9446052656478984520, 3720796795453397330, 18035355127900871187},
+ },
+ {
+ {18221138344920380175, 16761112742545021198, 14421639991115588619, 9419167563943683547},
+ {6237248361283446238, 889754338720059891, 2289880386545166424, 4280148734121099084},
+ },
+ {
+ {5259165122317589354, 6306061166879114159, 2622163270351284906, 15212813592118086979},
+ {11497359168652342849, 7085380391293263482, 11799059272489792659, 4912160901181298022},
+ },
+ {
+ {10512473611770099290, 11735037909076331019, 2922606398008539984, 2599799834378751770},
+ {10226702495047936424, 6109026252412854338, 15572556822827169237, 11993701786788749663},
+ },
+ {
+ {5106897453764491321, 10540479232768400094, 3938246597140945859, 13156157265138481529},
+ {4932443191001849637, 11374218582626530502, 2907557293167002437, 6807344711257391317},
+ },
+ {
+ {3993197157612782947, 14810882170056329119, 3476738916713041107, 1512933700383846542},
+ {17820889751141311776, 9132720567660500233, 17598924894608972696, 9704537908665702455},
+ },
+ {
+ {12121941964759747109, 161674837074510172, 2599887134944602725, 10582301831176576187},
+ {17746858667522793487, 10735346620578591475, 90382511151212475, 8756617880518165297},
+ },
+ {
+ {13269854730742674802, 16128423099443070808, 3557230428644480193, 9637953317416090984},
+ {6295039911768726240, 7019479692290635445, 11667616931857432446, 7159479331923350611},
+ },
+ {
+ {14416651741118525418, 10180867452897498870, 5073925566889872021, 17399294023945814271},
+ {2042657564518230341, 3364886656428812718, 6324877312192616572, 12778324589036538810},
+ },
+ {
+ {10574237360751578123, 5116798422805306054, 14491722292795290218, 10799156134310323684},
+ {12689926633011134844, 2658342468671191169, 15293758403109373386, 16248058473163364262},
+ },
+ {
+ {17412396133163580666, 6474892296180387693, 3334160446575187305, 12749216946172573968},
+ {18160154520597666127, 8818156595950176943, 16077267238396508593, 12651459389529897136},
+ },
+ {
+ {7837268594975894598, 3733413917041538879, 9408433334074005916, 9807113299110084489},
+ {673053561909802023, 10235823672366472244, 9197803481286702511, 5670973022205283920},
+ },
+ {
+ {4435804333677545569, 12530066828083700918, 14652119799285589695, 7610189145859517535},
+ {16049951379406478991, 1895939661259683634, 10886955028200106760, 10575752015672416378},
+ },
+ },
+ {
+ {
+ {7454214833719424418, 2128900810399984335, 8254953962723841408, 5341529923812819418},
+ {11486532916552139238, 4528331821405917357, 5048485034448492541, 4189495710753944825},
+ },
+ {
+ {9223539587116638677, 879142711399260546, 2878829560233905572, 13081522393987952773},
+ {3067261963348061547, 16008150780594711643, 5466468631453287640, 16659147898971349582},
+ },
+ {
+ {8047766502132608624, 8715815570878148809, 9093649079884580138, 3437267783531715968},
+ {17562225708466062266, 3512667182749067601, 9223059995161026858, 1366690634827047376},
+ },
+ {
+ {17929132376737482163, 5565926714491294456, 5252303555134107501, 8169975563698132305},
+ {1829326230943509100, 13780918661853274468, 17736665596871232627, 4246797342334307384},
+ },
+ {
+ {5113556452592134569, 7304867793218750141, 6016631926489320290, 16471860203547627727},
+ {3444471410714850041, 16571738096215232488, 2003912224952639024, 4203884000388032492},
+ },
+ {
+ {16858425223672505353, 3192567884201479579, 1688923188642613263, 4159042130811153987},
+ {14900413503869744297, 7521485042788722327, 14038093805562042641, 14713051866364662650},
+ },
+ {
+ {3738774192924465076, 14037618828827556145, 12882915396530927286, 10882862194263941815},
+ {13115222579444494605, 18244214260845794346, 17217867059738274194, 2458870331386500577},
+ },
+ {
+ {8768788172344064509, 2761897497254272960, 1400167175024837359, 2591319596670212133},
+ {1499652044223484974, 6820326453941021707, 9701009499879906773, 6897435972338565418},
+ },
+ {
+ {8314355711464256163, 8435944020779763783, 1814803522962187872, 1875253356755380905},
+ {8214588085484192137, 18062045700553127821, 6649947905482043494, 3119726140944397531},
+ },
+ {
+ {11881571666857493523, 6300786026612414187, 4928573492087752294, 18343550313462089203},
+ {6770642120472453960, 11296815027803718740, 17312916793783562794, 13028515123652649961},
+ },
+ {
+ {583508939637547757, 3195115082527873085, 8497784022800549923, 15135719419829981016},
+ {1180291993378114150, 5447281494912347899, 4710517655176242215, 606503081693490000},
+ },
+ {
+ {17732293765863716052, 853971165248416821, 2022886284923413326, 7522564752651732633},
+ {1417954193520965954, 5046659528429172066, 11426939225844711305, 17687206690616539318},
+ },
+ {
+ {6518552374736169438, 7940416740434530770, 15228615103587329007, 10662504584317997513},
+ {18370800756791469891, 5564085264882124489, 51043856061444814, 11996026931884728651},
+ },
+ {
+ {7009195269496826002, 18330778751427846129, 7903886241001925539, 8198930484643879628},
+ {5453546027419466587, 10378692433982210944, 2242412603379120569, 14762161396393277464},
+ },
+ {
+ {6146718865488327808, 8559779132928137805, 14001994895150170346, 9915701789711858841},
+ {17119408219089522083, 4345363585985782988, 7559492126634131602, 17074565022279033371},
+ },
+ },
+ {
+ {
+ {9262509587234749312, 6377906816499461739, 15415592259881792841, 6113140067088447267},
+ {17505803833889144731, 3922849788840338823, 6180172597177093790, 7272741317181956640},
+ },
+ {
+ {15620168851912893400, 13762314693487747007, 13577625382054330775, 4116976667540664996},
+ {712200332640207605, 9098568002202933512, 8905476951567380032, 7075673514150314660},
+ },
+ {
+ {7724870937269356050, 12054277107553403808, 1881284905431205309, 14429595888039183277},
+ {4176419490283315185, 803567059653412279, 12138878637145159139, 9651152331113389250},
+ },
+ {
+ {15811459837282651008, 4038049993244767161, 9054218236388056577, 10807376403937048775},
+ {11113869110590438959, 10336442539492421506, 9228056645601479672, 2983388754829658480},
+ },
+ {
+ {5272549712777700740, 3890998652469537324, 2338530655383446899, 13889100994494825258},
+ {2605827345546331653, 1946537408424111099, 5960128674616374312, 2996461229050766944},
+ },
+ {
+ {9235630643187100528, 7874836741106774683, 1509645736063284557, 1291934408179243533},
+ {2170879231846765016, 18243888082459973651, 266993053446290594, 4551583084211481457},
+ },
+ {
+ {7680050744092380106, 10728235076013009138, 5020205498410121740, 8174117988374987111},
+ {15823303896577313648, 6268651341788131847, 16646239256422284672, 7277830349937654337},
+ },
+ {
+ {7189376137127712298, 9147574701720272724, 3983921661449444789, 12479790317447783959},
+ {13221020976679959405, 13001868979553711359, 17918176319017234744, 18030393246529651080},
+ },
+ {
+ {1277346094474678251, 9498303380775859142, 5384923668452161486, 1780647986160100011},
+ {8642790494747200341, 9734232043260261391, 5142834828615817260, 13851307413031336094},
+ },
+ {
+ {13856162196947802633, 8991033151317963811, 9758143338284799726, 16669930361261935141},
+ {2769693485089420097, 14961618614592883242, 6027973048684521312, 339045855685213514},
+ },
+ {
+ {4705473345956039571, 17384553086897199761, 4490030246274451948, 1509996255726148943},
+ {13542663230247432557, 15148026535112827520, 10014941605271261089, 5488071105468657298},
+ },
+ {
+ {13903368497828271814, 8050546449078305498, 6932373216915935575, 16010012759059004304},
+ {15451708272653450375, 211711129247219149, 10435723642185827585, 17790507800712341232},
+ },
+ {
+ {11196283625212661460, 11223173364796389182, 15927254202510526683, 15939111530538795368},
+ {3486548927974609940, 8233744837082586587, 7138041412908951164, 12863368836600604627},
+ },
+ {
+ {587498550288996803, 9937849083717302378, 17460580580397185843, 16850270092759302710},
+ {8661654791709545973, 2350686583325065432, 14816283856648791595, 13021196930055398267},
+ },
+ {
+ {9641099975481205848, 5936405208377074167, 16926315209235053832, 9612898534540818137},
+ {17782980290875306043, 4118599702370009503, 5379494204096737612, 10529123509904334042},
+ },
+ },
+ }
+
+ @(private,rodata)
+ Gen_Multiply_Table_p256r1_lo := [32][15]Affine_Point_p256r1 {
+ {
+ {
+ {17511864284462479051, 4391315454785363822, 16633389246499252566, 4290325975494843430},
+ {15912670649662225191, 14172733821603328367, 12709802627494541709, 9648238681838878635},
+ },
+ {
+ {12840624483048662115, 13614226123606379619, 15087571995173849344, 1395488309690794621},
+ {7173958427217959878, 1198561064176820332, 16821886260165681626, 10019479169661217935},
+ },
+ {
+ {9901328250515532535, 12796305315632203942, 10819069447660403847, 12542238242508661240},
+ {17077777737462854238, 4364294351375777648, 8335244153165894685, 8863541604979427311},
+ },
+ {
+ {11029520456752683158, 2297291237551781454, 7934683676555855479, 1563954733146546128},
+ {2252805128528536255, 10523375695822939112, 4598652721256818062, 17493379105069761435},
+ },
+ {
+ {2747551692916263132, 3151123035150683281, 13938314333309683791, 11970864255483579560},
+ {7894236725861110998, 10515613623232567716, 10445557830757066839, 11155097727742050955},
+ },
+ {
+ {9569762631377921701, 10341967309273270300, 4697570564829842013, 16684762125903667303},
+ {5281929071085172097, 13027961546412671127, 18398764602992176314, 3872796039504642974},
+ },
+ {
+ {5035609627965208105, 6338722048255995169, 11594969687968475335, 5639340633771742838},
+ {6928934109570365590, 11589609913085167707, 18353534295019770247, 6879412911232288750},
+ },
+ {
+ {10042008593756684008, 6713471518385846030, 10961845838926538977, 855334359173719954},
+ {7598642325962297361, 18006511265377032901, 6844179774752820363, 248341098560552116},
+ },
+ {
+ {12797853895127133352, 17314687680589848148, 4801569699821499927, 9711604734594547217},
+ {8212610645535363590, 17221681508724305642, 11398663136094709935, 14918164175449979798},
+ },
+ {
+ {14940688064094792027, 10874356086032303420, 9942334156288812894, 18314945846365913248},
+ {2026773265909278528, 13079907189666226787, 2413436844382479762, 17172916412715413729},
+ },
+ {
+ {6906211734178583215, 2568977141255648055, 12122130143181371713, 828440041422552532},
+ {9361946962651414191, 8982763378443381215, 13842936470438971226, 14726899303190381422},
+ },
+ {
+ {15233793159839573220, 7091365221489488397, 7026505041428577564, 7614138360854053029},
+ {5906758210005848219, 18266182645583974519, 15465977441750183309, 15365799046100584430},
+ },
+ {
+ {5523310814149808824, 11103439607538154330, 10292039577546071548, 1169663949743807030},
+ {902203905701917473, 12346725749938989079, 17633270407605278415, 6960688675023695455},
+ },
+ {
+ {4505161139988645144, 10689463780805884897, 9379083335142738351, 1333253488693735633},
+ {16044931735888519844, 16145584549427855743, 15405407720239538978, 11239573776554839202},
+ },
+ {
+ {6975554318981968975, 15982286720404911512, 1685931425716796252, 17715405440768877495},
+ {4827607732096558544, 6375626601740689475, 3502039151843227915, 12085565714635174559},
+ },
+ },
+ {
+ {
+ {1190044221726873109, 732025666411072563, 7781096808432277694, 13079879637655900365},
+ {9048680577986693793, 12528346194104542124, 10575369576322629835, 14068913038053465964},
+ },
+ {
+ {3297775431071502652, 7947266993949467566, 6161673381820779563, 10604626734847205996},
+ {17669018066064502925, 2386071939136502354, 1076023928806956187, 16075459682742916440},
+ },
+ {
+ {12387028018538599950, 5791681577936683396, 7536922194386052138, 15377770247350254336},
+ {6564316170002440575, 10629371267149545956, 16125760269901494382, 16051398044897962024},
+ },
+ {
+ {6237354803374899565, 1782400080026955610, 16115027077529639342, 17907259814836219524},
+ {13179234383592426160, 7302978467158243198, 13607720993463749225, 6693531817169120736},
+ },
+ {
+ {9659467198848065929, 13765104107473534739, 820057324758632016, 16604163594878267405},
+ {15321524555426147294, 14524167419333362957, 157291234996957911, 3689488130722730671},
+ },
+ {
+ {13896531645245568605, 13598412639648980920, 3875086557856143664, 9242105512956135595},
+ {17410265178284161091, 14904754836127450463, 2354327747158525902, 3858493849578874654},
+ },
+ {
+ {17288438225198818690, 15275190140700748774, 14532856272428522409, 2192294551011758591},
+ {4275966798014984695, 13252812474545742114, 8604705074440591847, 504054699541924162},
+ },
+ {
+ {3623027910997185067, 15957466839356832933, 3504133700071704955, 4135728439139397021},
+ {1160600455691338871, 4431928072859292239, 1542956305318065546, 14109181184369694855},
+ },
+ {
+ {9135041378474229537, 15626265487594878380, 2645257479784082878, 8105679948445763432},
+ {8579715781576202730, 13437359533149316300, 4344754720520585005, 13326372852934103673},
+ },
+ {
+ {11341622086474305983, 17104958945811183278, 8154944722722765678, 6696975609844549775},
+ {10895966360082878017, 2277686037575837054, 12236842881540344526, 2086470279064067791},
+ },
+ {
+ {2942668817124399651, 11439025398519255779, 17477264434671471242, 9606507094132585461},
+ {1771475584689465869, 10791261379080046759, 12901998265727968789, 16423426725595035468},
+ },
+ {
+ {555419805011031621, 13715683285513290290, 15526654591995532751, 7023761423093873354},
+ {15093366433178982304, 8625749648874372840, 6412297471587129206, 12161114204724955762},
+ },
+ {
+ {9362623422820895267, 6491356159483508885, 8543224082493101588, 17290929683278258587},
+ {17348088672546490894, 3323350644823701753, 398525379151271104, 17794417664139368677},
+ },
+ {
+ {5880914635028486784, 2898124605786107494, 7953506026198179840, 2189477357380899574},
+ {11207122442953694293, 9288539232660208671, 13527697625010979453, 448462453367651162},
+ },
+ {
+ {11262205719433170585, 7539606872920196479, 492385789142086954, 16036594120332851267},
+ {8084547797138041354, 10063336189771527714, 2484395715469739911, 4879298610504146231},
+ },
+ },
+ {
+ {
+ {10457697409306668434, 7830477435299250296, 7772379952622394912, 6109610138112185532},
+ {4382803614711332911, 286231563340803504, 14408860285425706036, 9445290615796219321},
+ },
+ {
+ {8838210194055479741, 16190279688839291456, 16520121358582757556, 16768959728701970634},
+ {17279896910204983538, 3582816187015369256, 372137484481226748, 12972230207718993241},
+ },
+ {
+ {5372953569411270487, 17808033035436856194, 18122397266105109983, 7100719381161799491},
+ {14789750485957107776, 7797117101197801156, 3512936690589352328, 17020065099624467120},
+ },
+ {
+ {11480031272463364121, 2525856087688686375, 5875255653057452580, 5606696614467440464},
+ {12094715534218447962, 6173479337351577758, 18244015404482482803, 13199349349511499695},
+ },
+ {
+ {15137716704658930971, 10986987873306909694, 1939043496821343401, 831824210330752494},
+ {1056638569496361761, 1714583153436391847, 5183439003162975519, 1665087783666164342},
+ },
+ {
+ {8618628902870211609, 18064648431799903596, 7274877928823092285, 5660734703123876155},
+ {17178150811821260605, 5485275535084805985, 12607767610318589165, 2215859519135800862},
+ },
+ {
+ {14525253431314563485, 18061438239992695424, 3753059877845742067, 6434164734885086330},
+ {7925955539869645215, 5236273722884803492, 17135463959633855728, 1885217581414238490},
+ },
+ {
+ {6097225965006328457, 2630336000831717722, 7049638698786526134, 4203465038263485233},
+ {4677974565964393904, 16044036678123636261, 7266049959100300634, 11339674070148504929},
+ },
+ {
+ {8932509163442546090, 15088719838810504543, 16380598316811388529, 11816509227456545305},
+ {16117098651837966507, 6506253137957995237, 7842840841723336777, 14854630695614255489},
+ },
+ {
+ {13319400996902371533, 7582870533150862327, 3853021819016824068, 1553148791440569506},
+ {1383156799113954152, 15192818247458559870, 16096167687117464686, 6356494963887209448},
+ },
+ {
+ {16159738883836847557, 12797888767862801410, 14516904553705186948, 13070086184381080434},
+ {916885380224317954, 9486576895096666538, 2320292919516422975, 5019772534786350963},
+ },
+ {
+ {1979992348876614621, 7494083465935166973, 16035723662722831744, 6820849908885211777},
+ {16740735239901023053, 2017530162004533409, 3087262288875984227, 9072904925376793991},
+ },
+ {
+ {11716934526135332476, 433379719600995157, 14981324743710487461, 16580162143428931768},
+ {17678216037230646787, 2252837520490636634, 15914299694597684738, 15253999728204986937},
+ },
+ {
+ {15673599333229961794, 8862902775863712472, 7565222536246787763, 6724910605061440481},
+ {5835390808530098179, 9647776340035782792, 1038074137838521743, 3352456378381259564},
+ },
+ {
+ {13166325906224116930, 10408481058915151795, 13583679214409957982, 13238337156927685694},
+ {16088785436819834700, 15860660615594092228, 6472158593272826810, 15600310172166391652},
+ },
+ },
+ {
+ {
+ {16375505785562641226, 4903074653735993511, 10355787845763031761, 3188849033041803587},
+ {3145147452182864049, 13878747873108378466, 2798650520315922121, 2325962694441538199},
+ },
+ {
+ {11530583608023224967, 15979155166527001287, 592931868138800645, 5361781029549479856},
+ {11246418752830406096, 11882251984248471436, 12026389461944629423, 12289077922798223820},
+ },
+ {
+ {1328339467113622233, 13374824154992864223, 12057132015324007824, 8507647484414695512},
+ {9286016370798146986, 9083798709648036612, 4312959727577073260, 3732271624824420608},
+ },
+ {
+ {14129872794455315922, 16354810591314135702, 3177417010197743958, 16494351130927698692},
+ {16557765056328447818, 3139394196704738651, 16891813998271303650, 7374470997276173905},
+ },
+ {
+ {1547814412223404746, 14194709348405912167, 15771028929623393801, 10945048172868684389},
+ {11234483878611528405, 9542605377580701681, 4555391547268120796, 14916872217451960022},
+ },
+ {
+ {15490131882364039637, 5140304620645573547, 9403655757498826823, 9824850954989176893},
+ {6366139388903157264, 1981838834216345294, 14659870286877979556, 12091578124492612524},
+ },
+ {
+ {6832171775190531128, 7903951882621813138, 13717573220828409267, 15400575122727850054},
+ {6101307565293576434, 17226772767105983314, 3485283905347036760, 18439321272895583847},
+ },
+ {
+ {6289130721434350290, 16129337673129720846, 6648351866142453445, 7705983837166554199},
+ {8120136556582544814, 7924417299222764443, 7821995671300500892, 17697662726179084739},
+ },
+ {
+ {6669506511185916061, 7036555931205961476, 15471324228012955656, 1075869467462424743},
+ {14834182808856841386, 9481869408708862398, 193651363902981365, 3496053494343565969},
+ },
+ {
+ {15198290782478916101, 16205293865829644684, 2104596565474767471, 7783918193658109501},
+ {1567469099169331732, 11324634977690198924, 1374141643017900909, 18368642394438425630},
+ },
+ {
+ {13389638006727712302, 17518324493263447682, 13178832200681259657, 8955667391164524441},
+ {9331759525815425703, 12920722511913101049, 15807602761711044426, 17873219821625976662},
+ },
+ {
+ {12103811390374960600, 2801185238127939998, 16289223959107648345, 17243660994858386104},
+ {14818957729322960498, 10018491794651971206, 5502065678180783560, 4158378425043433526},
+ },
+ {
+ {10278921174996593635, 4630624563386647486, 11179643216044347020, 8701826069861381281},
+ {5839989039471676569, 3060138177923841885, 11279648082143612852, 15207786733412131883},
+ },
+ {
+ {18277950978951138342, 2577918906618404946, 11684553042740786163, 3082582313241836872},
+ {5222056779189126973, 7794579876203167869, 8527673475629739407, 9851790541007784515},
+ },
+ {
+ {671618501514350673, 3455246317052893537, 18161533457452722900, 8968434886308785175},
+ {8445049055511813064, 16897132794064300993, 14420937999674600470, 11110627336577683437},
+ },
+ },
+ {
+ {
+ {11535283160083833975, 15102917952496589829, 12909095696891909745, 4611119212602854744},
+ {4195756524232932570, 3754603965149529000, 11539276962358607816, 4401424391553230481},
+ },
+ {
+ {6842993463058627120, 2708745114617181146, 3832382691810282630, 10333834458057320812},
+ {15028197197004077388, 7681293343255119354, 16227537691626587485, 6703363869832495607},
+ },
+ {
+ {17567108285065737529, 8693245930330183070, 4025672038042952121, 3491067119247522844},
+ {2100799837993193702, 9579542950705774054, 5091525285265581997, 1806757015709820088},
+ },
+ {
+ {7757354840118131559, 16227348978414023262, 5800861674805516343, 16486235803248700961},
+ {15646700163023677309, 504258765210816549, 13724147899924699697, 13588899538317277096},
+ },
+ {
+ {15895596198730294923, 12513494396374459899, 13552575153453342654, 11312160635199213507},
+ {12446618129881485796, 11286186116805515445, 1584191291800429567, 10188741008566636830},
+ },
+ {
+ {10157626021970320469, 6580688164585715207, 17158416694471177787, 2873484006255074946},
+ {14852216457444863041, 7463041347566136496, 2190030775722958628, 1116223035803602728},
+ },
+ {
+ {8598875756176012541, 2146658618778432566, 17575736667490551813, 3602654209723135985},
+ {7223347129734689099, 7256921024940026570, 12249118963297692963, 18168532365040819099},
+ },
+ {
+ {7585174044375463988, 2491923406404093282, 9355733262044036112, 11484079611349577325},
+ {13145030009254943291, 1234932884591406048, 479845670619308618, 87735010308690865},
+ },
+ {
+ {17307641427543377277, 5862898330718319545, 485176909118483750, 9845223919324484076},
+ {4293549583740204024, 12765124043303931186, 17870894781132657382, 6508172378961793849},
+ },
+ {
+ {14234156373312856400, 16210939788814051708, 6478880037923038392, 10435512103812909561},
+ {18142844321802359753, 3243996803126554757, 395603619159523019, 10213589535656704607},
+ },
+ {
+ {13256075137060741204, 991285459654295161, 7857174835799942102, 16201105040554625727},
+ {18398612085349994216, 4512860776717176840, 3521452275695011919, 10622137733045360311},
+ },
+ {
+ {14993897771652736376, 3320388672992783302, 18421556740970114213, 7438967127794745135},
+ {15048397725789819354, 12721899159423777001, 1135125102123667189, 6637485660805148630},
+ },
+ {
+ {205606553319362431, 15484041062449893984, 12896720585684759529, 16675624014916513672},
+ {7579112430564108390, 4602460356900251082, 2677787525524280838, 16723483619407414479},
+ },
+ {
+ {17981939084373319995, 3989926231875116241, 15342509934701840045, 12999252495311233519},
+ {15389919024942778009, 6136335679373143315, 4117381415379544275, 13342256463740646775},
+ },
+ {
+ {7622769999043907199, 15227992053145045634, 2719412067263856950, 17811161335980566241},
+ {15036003689029442301, 4919601685231030712, 6756893600905532338, 18029567067112075531},
+ },
+ },
+ {
+ {
+ {8492025373682814159, 9341562763134230960, 10104358220305514878, 17545404790574939459},
+ {15737064134098795026, 3880597485411313924, 388663918823974597, 15032915458906101183},
+ },
+ {
+ {9452334891928331309, 15207477416486363718, 8081596400773698461, 7528187414539292243},
+ {4773782664413845594, 9435822414884353799, 2722451711480791323, 13642248100035410269},
+ },
+ {
+ {14202843175914986568, 9421566354325954710, 8667368258699634314, 8733557788892402517},
+ {331451278037425751, 1109013653863287548, 8802742738207038150, 4667769857523050796},
+ },
+ {
+ {16570512961992288509, 15784840936011612960, 17797638261217375128, 10589124475671334830},
+ {16848440972121709899, 697679021479737566, 1456738239410270672, 7214966028857473701},
+ },
+ {
+ {13782421991242364698, 14661156263311647121, 4726455119103158850, 5026680986111581594},
+ {15610213195880130268, 13703306863846075517, 1371700218221235399, 16792392307217237043},
+ },
+ {
+ {3250188629442787152, 2728518744775098354, 3140694818026767341, 17566141747707001105},
+ {9569291890730505101, 4439949820491175035, 13751802166620923317, 6602549032413906269},
+ },
+ {
+ {1067242659333881602, 11852011445832610026, 10644339539182752718, 15519552867360295119},
+ {8817864336906465495, 8844034637292547409, 8850766994595652906, 5299330403389585218},
+ },
+ {
+ {11434157439953722433, 9090860151661100670, 8407869262026581159, 17882547383849407986},
+ {5277257988019769029, 11463853580825342183, 13607489835500075467, 16878800997498950751},
+ },
+ {
+ {11526703690786988415, 6919770449526881259, 6713486711636442468, 14697284704991333147},
+ {5405738839499060129, 4737011393825878948, 8707677918280383477, 16881185094380241198},
+ },
+ {
+ {9056014389564242176, 13179419520216397988, 9815298409700670396, 15302091100015307530},
+ {12552178314548371153, 3975519917079954227, 17211203317279781814, 17755252427177154090},
+ },
+ {
+ {14056502343958951437, 9570378325961888046, 18335930130582329417, 12188057598786655680},
+ {605832426765150582, 15265028749599155713, 4881763628803375168, 425422732543303669},
+ },
+ {
+ {16059297404709367406, 8426877510924536482, 15269952608796785555, 6256768900860981984},
+ {13142655793714702073, 14566340391957173918, 17147065283704191109, 879106195264399},
+ },
+ {
+ {14152733561556558931, 6788431167332998309, 2303657738205239031, 12712406085467592411},
+ {1740483284496903693, 7206807366776489586, 13420608648010812358, 9180900918550128115},
+ },
+ {
+ {7193311017682954852, 7916342489073401148, 7990830552202175554, 15066065171478273830},
+ {15601436495559985484, 11056245839590890541, 15963012082312968312, 7270947051909344657},
+ },
+ {
+ {5010740583028703301, 15413348048560455978, 2028314374959411194, 16685660750422250777},
+ {14284468905357216559, 13715859397068327775, 400943255937053645, 15390787503961331119},
+ },
+ },
+ {
+ {
+ {2707032230021934480, 14943945588296447659, 13333962501998857701, 10603744732015256400},
+ {3386903941135274495, 8507451908469049716, 9231176235773710950, 995464562185179329},
+ },
+ {
+ {1497127512412966214, 11292269970549257426, 13920714718237672232, 1363993524078475237},
+ {3687544717271789391, 14097532154250414203, 8367320351336033564, 11089672460564007700},
+ },
+ {
+ {16993953276024768829, 12025590727803527383, 2672535181364381995, 2183111709986676538},
+ {14822521615475063339, 10618745739454592027, 9957515072444869664, 4797521918890127374},
+ },
+ {
+ {18097777493026370528, 398882723487597643, 10462164796529820357, 7704526739683689547},
+ {12438059168025171393, 8163001730991802064, 3319372757738711275, 11518015261707325261},
+ },
+ {
+ {7809927122217534998, 6003738786706135597, 16541272992243715653, 11352602417510156921},
+ {6070703545889058045, 3742828100079104877, 9416263310824977145, 1406892456840131842},
+ },
+ {
+ {4005088727670892586, 10215872293486093012, 7634075494800881158, 7707144163086802537},
+ {7085702388211248163, 12168208652772836726, 16347414703478252736, 9386623607672009940},
+ },
+ {
+ {16530167766100505402, 14672843572926881623, 10752276706209340624, 6888427606311779724},
+ {9060900993058482991, 10439396339124215720, 17640982730425880863, 12916411341252677116},
+ },
+ {
+ {11776245660806714247, 18129100488268011560, 15389929343761297429, 14544292652959164154},
+ {18063319363114104433, 13433144948667100183, 462314076175867487, 1862686058702915115},
+ },
+ {
+ {17306422602774323327, 17272002328208118653, 9314885036861009829, 7485631191912561636},
+ {1933835651414138452, 15231897024969540970, 507247317572839552, 10741595984991150047},
+ },
+ {
+ {18297797979313130180, 16976628082093243813, 13059060093619519046, 6865085966096869228},
+ {15021840537243000183, 17843637254308940381, 13122764022765250336, 12556030904692962295},
+ },
+ {
+ {11175787671000337381, 17757097628648374409, 13408571223487217321, 2720103532070247452},
+ {3237822932023459208, 10155101091021157316, 13910068101949253623, 648579517754264097},
+ },
+ {
+ {16597587101652675879, 3941450686064909756, 17635514250964078220, 13107347044039852240},
+ {8910347370050088758, 3114023981351548745, 5209360756412143979, 8990623441581200588},
+ },
+ {
+ {7692284195082081732, 15977071788000084350, 3594719301791478282, 16545490512039598136},
+ {7629535887569375952, 3241949087900065139, 170526822997903747, 3422990592513330514},
+ },
+ {
+ {5473399325468482480, 2511351254139828397, 1124856552206019504, 210074180589003934},
+ {9693298849967626723, 16185054013081266938, 16070865229793723400, 734500463998096984},
+ },
+ {
+ {4895849847827915947, 15252720925614851036, 5944268852782996266, 8171510665067151601},
+ {10594809041696466609, 4377920841124876663, 3816206760439007336, 17150624011379500381},
+ },
+ },
+ {
+ {
+ {6266830413981331818, 10890859480409122410, 738708598357264321, 9241173142142102299},
+ {9152169484987657321, 12122430118903337055, 14270062735458703743, 13877635605034675649},
+ },
+ {
+ {4572419849863661964, 16330741525817240677, 5456771007607263420, 8798510164381810403},
+ {16547183593064549865, 11355135595370359779, 17581910791451710925, 11684604415749005488},
+ },
+ {
+ {2766130068233451740, 15909689412657372214, 3272828023364980896, 12907534005596438003},
+ {7065629942275705493, 10609982651084321649, 17330343421617897811, 1746246157222856918},
+ },
+ {
+ {13168953859078137190, 9072500190247791267, 11090199374278127099, 3503847851309060744},
+ {14395788825673846582, 15073993563711333791, 12879874391706003251, 15417028700542288171},
+ },
+ {
+ {2686132933630431595, 334448852204016400, 5636563341880055087, 3897420469445246068},
+ {10569177829735084588, 8244586887721364305, 17973493209847502315, 18083956436923498083},
+ },
+ {
+ {15514509130323617046, 9833490355170899102, 12028021566105512521, 6349458533674010018},
+ {13470024118569549588, 7867188201997717819, 6110792121234766402, 9917858515766574695},
+ },
+ {
+ {8273062939911446888, 1936638151089648185, 44602505720759914, 7839132833110815763},
+ {13045756168264521992, 5375972549477973022, 16964151563535745964, 2871770426902555432},
+ },
+ {
+ {14164643693563803212, 6386904235704679249, 931435629437735510, 4496152555914735639},
+ {820099532545743339, 13419988718062417698, 8948965620484833159, 7238410427920554862},
+ },
+ {
+ {4387941928212462673, 8023190031094282215, 12322462122895470016, 17311901330042910195},
+ {16445894183838823370, 690424095855074674, 12820742226551488738, 227935274674223825},
+ },
+ {
+ {17437729542205914525, 8439533239207225162, 2862942422640746698, 7340866642549630610},
+ {6770451500989398335, 17262212260581413381, 2156505157624055602, 12195119268846383898},
+ },
+ {
+ {13685370053507732180, 8304030489296890211, 7042719123662732989, 12115154796394040286},
+ {10496877583013829980, 8909625177349683785, 5268451666475070682, 8910488385056259560},
+ },
+ {
+ {8874918984373509240, 6652428549855789281, 14866714872885601270, 12093494664302554643},
+ {10149999253136441007, 1611873554177023520, 10271627298853910516, 15171882630355491729},
+ },
+ {
+ {17085353800722834618, 3271271583189511718, 9338466116389304614, 4685545953421459012},
+ {5059702655119414343, 201476627889215522, 6388612869673101372, 8357217932305360896},
+ },
+ {
+ {1836621694151238424, 11438765101326043062, 5537182303007083642, 2657011195641217678},
+ {15370176245454161308, 1478361893117141052, 8729368992402422055, 4807782542738120272},
+ },
+ {
+ {5084555197036037383, 500829604818691390, 8128181767026348964, 17895639808733462562},
+ {4138748420878083709, 267892430674902987, 8954358455330696651, 1946224964877667668},
+ },
+ },
+ {
+ {
+ {17561670470565298976, 9524122142014309347, 12619871254022879995, 4098610542031538614},
+ {8338691110372464881, 4378598564044777665, 16435680634249352743, 12067828180476756532},
+ },
+ {
+ {12574920924242276218, 18146097977073890534, 18281543194137545725, 4432773597060264867},
+ {797962164984225968, 13432184750641235201, 12394976215803938078, 3054137600383896411},
+ },
+ {
+ {12910897300898239001, 14116919300756610521, 9737100313909655285, 8792063194563201934},
+ {924297264228895146, 975866810375743708, 14953819883516375119, 9992561966868201517},
+ },
+ {
+ {18270562314314829224, 17574550722906577917, 15522987576586641271, 4200899284963891561},
+ {15719788437321868967, 18390235318178988753, 17371818886753265385, 4583380351670429228},
+ },
+ {
+ {11290716045321163897, 423611636875887759, 8716385793549629027, 8029377844845093468},
+ {16573848460451650185, 15094868140191104543, 14624483608434776103, 9086586764934160662},
+ },
+ {
+ {1320522168839874087, 6395673054871725696, 7793960979093413321, 11402054451286901177},
+ {17278080290632229040, 3823680337747309837, 7840042035002848151, 17839593774203285281},
+ },
+ {
+ {10024545625018137606, 3780616370895328213, 1516632588067435378, 13846630703933575818},
+ {14323905768888574358, 16062987352815864444, 13444338098535013457, 13400662018607341910},
+ },
+ {
+ {10102001197913431240, 6211688443233768420, 1986665099237206297, 9248907879269017005},
+ {3081890249882755206, 7828527646248386813, 12676034092230326487, 14655968027461080131},
+ },
+ {
+ {3763532248936424432, 13507960710132312440, 2003243330622949364, 8723351916784911918},
+ {17411870179533482591, 495549359712213584, 6958432541445845486, 7674356092204128350},
+ },
+ {
+ {11814337248412299972, 9347461245743305200, 15456560932072269534, 9579754357941936175},
+ {2098168907840746456, 2063921976437345588, 9267808714920405578, 6482702408130663270},
+ },
+ {
+ {3313415711246730386, 4607422129142883607, 278072683866121896, 830840258180061490},
+ {16961959739026004139, 7896385585906900106, 7610238284391475173, 7231671772874233939},
+ },
+ {
+ {11464797300361906821, 1444449385286554508, 12433005157477847389, 964895564896662942},
+ {8457290958728547067, 7044433897330872257, 12292673928275053405, 13679355097865192207},
+ },
+ {
+ {15352304695586484723, 1527883079108513336, 5890042963344522083, 13407971103520766077},
+ {12385239629152188662, 315706510218287516, 5361117161753711484, 8824676525356150938},
+ },
+ {
+ {4555925933619499493, 14889603365479712329, 15898222225673484215, 878884802170861101},
+ {430001626591485427, 881428142547721183, 653855015067704092, 11378990354467312809},
+ },
+ {
+ {10219225570653005145, 9205374019534090202, 16828986596058027743, 1089575570166892706},
+ {3079144130112884386, 4682944567048139400, 7674497449298779575, 14137535283566239898},
+ },
+ },
+ {
+ {
+ {13266892287530449189, 2232961926857263527, 5934654989155432442, 5415975493246016158},
+ {17117784386882463158, 3875398271691758986, 15755743581177209843, 11380746535012415659},
+ },
+ {
+ {10162459499000477259, 7534168794800651527, 6320985751131807192, 9263840233901040421},
+ {12178625283764017250, 13143797113231152006, 13089053551699608219, 13480464010111258056},
+ },
+ {
+ {11426681347395118622, 17135867298562042628, 10870734720453621112, 13803364322975322217},
+ {9740527283062276630, 13765238480893165263, 4792349632705804116, 18359029140065847048},
+ },
+ {
+ {1420251412241033168, 6449255753238336368, 7468624722117319576, 5716072259994197219},
+ {8165015263320602150, 4757529151848960259, 2040364517493350115, 11069642333484542749},
+ },
+ {
+ {9434687670958330812, 4808705744496679962, 13910334628239183613, 2628594509406050235},
+ {10055911465166862298, 8069256921143792190, 11886968715847498191, 6351594160398684406},
+ },
+ {
+ {5472832021993175857, 6120966193470238758, 13156950075464061259, 14833372202848630444},
+ {5760885723102571027, 18022572190906170343, 9870918995920897221, 9546055667466056471},
+ },
+ {
+ {17124591880405051324, 3379747334483646957, 2084957978131092947, 2413497199486596627},
+ {2867893699156486423, 1357836849049583382, 13607307985344221035, 18039194570940763745},
+ },
+ {
+ {13230815692170010235, 10662664037814374845, 10120384214921531334, 8892863196093018212},
+ {4443096401408136417, 1896901619181196514, 739574867683694091, 11233952771600927581},
+ },
+ {
+ {13885878918475208407, 18415131106660406656, 14362601436612948914, 5740711586144226035},
+ {220574937152712384, 16774016249557318959, 4658351269477373440, 7890975779439252404},
+ },
+ {
+ {16628715286876183012, 5300385226682547206, 4493053153469218188, 6690552861098862065},
+ {9359345201611660030, 17390357193161728482, 9283655448484665614, 13747647357786913441},
+ },
+ {
+ {3101241556869117917, 4731590937333975732, 8347709942856514723, 580858462407103829},
+ {8937550160715031857, 563888416351720575, 6928865729903641398, 8295908905021542009},
+ },
+ {
+ {2219303446125808132, 7766409607764464233, 4492816761527421087, 1687012079818776091},
+ {9967512906892097592, 8099397263797608226, 264054732854154094, 14515622825083967497},
+ },
+ {
+ {10586626338424063837, 11285305220583812031, 1552873676034063335, 7108571382532772330},
+ {12077600502438115659, 4925647731241250576, 887903929602864140, 3575833277214438245},
+ },
+ {
+ {14685642695197717757, 4830460343095831969, 1748938116371486214, 3212377924501398108},
+ {7575821759023381902, 4416593227203343304, 17810665332121047202, 5387420006905173437},
+ },
+ {
+ {8644732068940188724, 17116805484232699355, 6611042643736763845, 12686480611232016266},
+ {13422256101258226329, 15901664205323922499, 100273141428472746, 3184681836469139902},
+ },
+ },
+ {
+ {
+ {2754563581284692865, 11257360722362829387, 8254261291934606879, 10023569920325096229},
+ {7980898855627864603, 17162063449612285703, 9275759455936104363, 15936804738099638644},
+ },
+ {
+ {303387668469489035, 7978391052264888020, 15413722057350324494, 508608987485166058},
+ {5585753287556892522, 1344134516582665443, 15144279405777509214, 17014353449841567149},
+ },
+ {
+ {12518577022215294774, 11347384788122950558, 17122718824958020364, 5431993665805279177},
+ {1445831254446028321, 9845654210244803480, 18315778529692612284, 930563922336183289},
+ },
+ {
+ {4894710987714215219, 15704993603878996107, 1606204036324478223, 14308635149530198932},
+ {5026736228773269251, 2911689442372084137, 9004077539360196849, 7770049130277452000},
+ },
+ {
+ {2745120518194234905, 17255944807561408883, 7371907591838942770, 11781525288383871227},
+ {7814952754785494862, 15022715213812536212, 4112388658963418656, 13703771908397991335},
+ },
+ {
+ {17455440140812341569, 16738670164475421762, 13259904130186215994, 2168106064304872507},
+ {1969289843772256992, 9025317999701057831, 5835661391798891929, 3826587698101558069},
+ },
+ {
+ {9149648374608464235, 7248346993716635643, 17283919168525322365, 10107681064815728795},
+ {12176813938029507719, 15110337574289033068, 2436453685316043712, 5876967059744625564},
+ },
+ {
+ {6197919059881189313, 3300993078638782623, 9357667752372201437, 17688129755135009447},
+ {5477090746558113696, 12602024521188880300, 15889961935507293355, 7135039746373941272},
+ },
+ {
+ {12561063426893244305, 3079971284510744316, 15695857190375815873, 16730673956207425338},
+ {12065477821845465116, 13846158368121919228, 2126156187526559500, 3005167441915916768},
+ },
+ {
+ {3858987859895327040, 17043903959888117395, 5861237635520080595, 3292646198413575902},
+ {14286644557048422360, 14346409530388980974, 12583555046601155161, 4665981927428063991},
+ },
+ {
+ {7657686120974201842, 2388299767028319466, 17934808017791217639, 16708640707026372313},
+ {14122341266134976486, 9547124998857374491, 11194069918436025923, 14657538980930727877},
+ },
+ {
+ {18115789712912297420, 6543740714573413570, 1955886376702349613, 14736853369719086334},
+ {3914330395250768396, 7607848156418885173, 18220633528980056514, 11930952850158858930},
+ },
+ {
+ {17010681753474701341, 6961088634819162945, 18395881317121515295, 11611411242007267179},
+ {7996717433149311639, 2687736005475404867, 15340214362731923149, 7116441414289074727},
+ },
+ {
+ {14302198697220662403, 11915041511943922518, 12363437164440173650, 4047410026894059083},
+ {11439743031696133447, 8776097395071907030, 6851061783357383945, 16484733576581941012},
+ },
+ {
+ {2861660066704264713, 16453202148771053225, 10039035813504063627, 6275446616881871868},
+ {7150609984920482782, 11100941755544354363, 6219760433202580646, 2875377482232912143},
+ },
+ },
+ {
+ {
+ {15290817014272444879, 8012864091692295774, 7591940515496590516, 9299619125326026848},
+ {7297256232167521068, 17861204372399797627, 3100022958796565106, 15313770879200204613},
+ },
+ {
+ {9902363248877274636, 15776195244792726061, 1935342462634574355, 16572507349421626602},
+ {7503944294807242065, 7454248748618678609, 2837392985175901475, 16494567631149775512},
+ },
+ {
+ {7821919851875204434, 3437243050078433703, 16281279739393410040, 3105985403882097775},
+ {6392071520880083076, 2042340026857542253, 2492719020444109453, 7325465357665053546},
+ },
+ {
+ {12299242278498309265, 117303082144788574, 18382936515565701803, 7941141688858846015},
+ {14923823358299367958, 15681089039073030752, 16878721085421212785, 3933697483394042011},
+ },
+ {
+ {17669228922922186836, 6423621568318435743, 16298886067880336557, 11009276012664659704},
+ {2934438101395245878, 7492928446481808311, 1311515713186855284, 4493146166488261630},
+ },
+ {
+ {14009653500169461120, 12982754496644678513, 14586034645437015762, 18126832542767444974},
+ {627541781236454235, 3801503508930355635, 14654684147782092084, 4179096323459534629},
+ },
+ {
+ {14829342742512426992, 12453047655591346244, 13146459409240287380, 18077963306248855764},
+ {17149389409735171474, 13591892902058002302, 13872587256559899629, 15878632005942819501},
+ },
+ {
+ {2878536922988449879, 8819365314325664735, 2696760638950720974, 11357179421800829605},
+ {14730809809256560583, 16277258726425730599, 13189689275745970592, 13769784951430309444},
+ },
+ {
+ {14706229979050107962, 8679247682181027680, 9705538653507374238, 12793525936716723768},
+ {10022723640772366793, 2224403391050849804, 11511158380587667232, 3250960576892370870},
+ },
+ {
+ {17671892277522139639, 1384260767972381005, 7623504419117295292, 11197930232971575240},
+ {14867469242175831789, 897596747715880677, 3892483173599058531, 13453254609965163080},
+ },
+ {
+ {2690362926234343281, 12134546410412600166, 15715872358030533545, 18160163251393343275},
+ {12233720002415141519, 556081697748597124, 1099809960955937522, 15489604457800724223},
+ },
+ {
+ {10292669945637125918, 13595563061674492799, 18301330068714272653, 16981073598172019270},
+ {4022713583718555211, 847970754090163894, 12867993617169467387, 10021141621864633865},
+ },
+ {
+ {5408393826294570360, 16896935186698126584, 13028972412622343885, 7850626233281656805},
+ {962076344521148275, 12332350290936839731, 1774588207039851940, 17877147526933423087},
+ },
+ {
+ {11625440764115934244, 17372224561416726989, 13457342366450471135, 1569549943944038472},
+ {17753658357081801983, 14093490077993040859, 1282770820260996510, 16402793994329437670},
+ },
+ {
+ {13086054618104175873, 11714492854942191582, 1743587223054035136, 5474094059388998723},
+ {13150833497051757606, 17129392131927259958, 5739140380294248045, 10239738807213437974},
+ },
+ },
+ {
+ {
+ {3631886121917081375, 14286411187847401959, 1546298555066841633, 4790996540037176549},
+ {9541492152219486842, 12304868498960755609, 11426775785781090329, 10793898029125361155},
+ },
+ {
+ {10932352970046201499, 5875690226460998551, 3699681560657289718, 8665743594825198441},
+ {10232089728487302472, 15664572298733091969, 7267222702489958195, 10552093353886118696},
+ },
+ {
+ {4008236965647744142, 8547116629188387980, 13874587567755370880, 12696453513706541959},
+ {10752386832421030566, 365775083075323708, 14295272684753058141, 11024897725724291722},
+ },
+ {
+ {2399232949134869057, 16408469118941953277, 17229778225562184411, 15990256768949242309},
+ {10694906341686584836, 2816242351659628719, 10794163145486835660, 15601904974333104002},
+ },
+ {
+ {1158521281204350113, 6232098057848694897, 12517518152351190341, 17852831094628421272},
+ {11653774695260269881, 4420518556213490728, 13835371272800239099, 12119809446886544909},
+ },
+ {
+ {5143546864201185527, 6400878864024957342, 15513803558106064076, 6712861984922181478},
+ {15623960351786428150, 3094277713920675576, 6184647748693682810, 7857605928718754519},
+ },
+ {
+ {2219152199405421709, 5367881810186787185, 9606063680551349934, 18233690822105957780},
+ {9941441403610160291, 14996958158691873775, 4936282940888570414, 16608409936766385729},
+ },
+ {
+ {13270099407878039596, 11569032926557804346, 7759575992876193458, 8239088820951102451},
+ {9633607727685959064, 9775909232917811341, 12297921731498614906, 14756100221590046549},
+ },
+ {
+ {3076166255574886489, 5587891405059542759, 2449830540875545916, 15616237426524550707},
+ {17820334717580127167, 11506219580693301288, 15242532286743473103, 3266057695402840388},
+ },
+ {
+ {7193168093115966016, 8050992763687139302, 9734357192061785185, 15553552690657851227},
+ {4632257996795951659, 1007158456255834509, 17052740163052114844, 15619284827675470063},
+ },
+ {
+ {4224824291132201768, 5709863556852834901, 13539485156399791894, 10330250853413634451},
+ {2817020820518906625, 14306724568884734914, 10421968182740721623, 6943068506740047695},
+ },
+ {
+ {10830476567180688368, 10003074695797360184, 5589380226277136479, 14952961630386717087},
+ {6354514974022878533, 3426762794422332369, 17950815054280597743, 14940277403242978595},
+ },
+ {
+ {14582622177810553114, 2819236216667324430, 11333005326119114902, 15900677556115860419},
+ {12265999577465855236, 14521351376076108710, 3999293994697120555, 2365385934872188434},
+ },
+ {
+ {1803647016552158312, 12981833819573589527, 11371133227762071, 8210800033974528109},
+ {16927172347295306236, 11674533305143999306, 1514600283696801303, 17036724058500952986},
+ },
+ {
+ {15551380071341300893, 1378878534597097794, 16601031904934455368, 14515377519758777108},
+ {7039813638645241317, 12524221355672362377, 10483072291636269482, 5711815649533531303},
+ },
+ },
+ {
+ {
+ {9246769514475702626, 5788284997389507365, 15857897362850327403, 13864676801095094218},
+ {12881526722328523267, 2620841421323221200, 12599981775316397124, 12820989846844560040},
+ },
+ {
+ {13066648645100247757, 16727492115601921665, 15749471761440498106, 937594351871983779},
+ {8381111811209734349, 10884357918725639691, 781591570669492079, 12778743765298428266},
+ },
+ {
+ {1797915488494232282, 17274756142259274463, 14207994319179101777, 9405903752538915237},
+ {9001743317941152797, 15048752608061590843, 4925745663463425863, 17143694017177138485},
+ },
+ {
+ {11613437975225156304, 8619196433402562266, 11907033287998837424, 5056904365610561965},
+ {7637552956459333558, 2827449950719061527, 9998507085256853501, 9238562885525900325},
+ },
+ {
+ {13246436769495027717, 5445015753017977819, 16266739009580878036, 15566606095998238977},
+ {12196078605380432771, 4854324313875295137, 10974170498288217052, 6425550765546527417},
+ },
+ {
+ {14574824159194628650, 16992289415800830701, 3499062703303067574, 11220872042664151226},
+ {18135860701984580530, 13630928571014923388, 2913126838766947469, 15869180955632349704},
+ },
+ {
+ {10621010745328025245, 14637275395423748577, 12928463178963493980, 3270672471462681194},
+ {11765440832075775157, 8138439106739837848, 10004644076263261924, 12582897670868871780},
+ },
+ {
+ {9605391611675301152, 14014632424042523224, 4638465078692570733, 3013469722048440965},
+ {10972600060210514686, 4497572559400894366, 2652629676209366276, 15827846806499715082},
+ },
+ {
+ {216774559418075105, 7056732230404238374, 4342481467357759950, 16143194646968227790},
+ {12304857685680249595, 5021239809847286634, 745754913624924064, 1603290801266214539},
+ },
+ {
+ {2784418922013631805, 3554650219010546629, 8896448905401216908, 13445015286698819482},
+ {6508982623352460996, 3322529327934132311, 18417788670080975365, 17554108945303789353},
+ },
+ {
+ {17620122226715347133, 9738429733440215024, 15577771434516492888, 12422193389576942718},
+ {18383756008252443605, 12736926759685644351, 16981429110294392086, 11999528928951986433},
+ },
+ {
+ {14489177617081844909, 15995916840320959685, 6361381313838994395, 11146176143708648759},
+ {17190512001934479207, 8406914945663974955, 18073221191428103088, 14075266763636071788},
+ },
+ {
+ {11493260321718935244, 7134447477334726345, 10489281872281557152, 6145540581503915475},
+ {4002857892747271740, 5167943945955725680, 2892864850826359384, 16887114279977647596},
+ },
+ {
+ {16493058314197913501, 14642843949567816202, 8421201635021034279, 3645913604138483317},
+ {6127272877310948153, 3660286308390076870, 14343325047340052700, 5355450922054278073},
+ },
+ {
+ {8426383571761073988, 17627146217941553397, 7396223609641674418, 2402241526082789613},
+ {4067059813672963823, 10306840429023537942, 18342506396531908477, 7249869764848707701},
+ },
+ },
+ {
+ {
+ {13937553904380032591, 9165760362893872288, 14159606902675650669, 7794101517494576908},
+ {11994596892880464164, 16211278212275417034, 1568324133241165712, 6579463633356173526},
+ },
+ {
+ {369660229032730089, 11851915833529805698, 13485269529443969890, 1270120511649175022},
+ {9128783725626301238, 6173048611666804214, 14151404531169195672, 18241008099921643437},
+ },
+ {
+ {16331025972320545471, 6852381640421896437, 9324740413214863495, 15718339035381717722},
+ {1521756232012903545, 5431459367124818841, 5364830919043042094, 11104748870982011750},
+ },
+ {
+ {16226789363155700046, 13734705589524056856, 9629995513492843231, 2636144377026081617},
+ {1233405076007260313, 2119672919365858964, 4932766292290315579, 4185117177904214366},
+ },
+ {
+ {6556637108078954923, 854911879338322327, 17335608616262058670, 8212786550755149003},
+ {8111194132924193031, 15689965289081013375, 16641361924274000294, 13131032775030004856},
+ },
+ {
+ {8653575060724839982, 11482527594744353256, 10837608928215660048, 3651629796762058243},
+ {7098570919231943894, 16903422906687575782, 6449467519885582678, 14455694979526406871},
+ },
+ {
+ {781149662684377075, 9606778745577048892, 16642923833572014687, 6804945833779567806},
+ {7749938807818369385, 4119995592971432914, 17172069782410404367, 11558710124840085255},
+ },
+ {
+ {16996170392430604056, 2476294162951949891, 6677439492116109133, 1649550562276235959},
+ {7307278264575968221, 17128676264244010843, 9768062299436691373, 3825325732056225433},
+ },
+ {
+ {6593955722549970555, 17069122731812152854, 9033349482403834703, 17728559655579364768},
+ {16586780540128534825, 13307658170018069777, 3129405955501687685, 11183053750385689524},
+ },
+ {
+ {396019325068553604, 11523268935121791712, 15099363117146465288, 15263791092270534216},
+ {13442484747453660303, 9234120847672647934, 12419564747087042045, 11765927783051357577},
+ },
+ {
+ {6946885342337567475, 7614129273290805579, 5593360004251714058, 12661112521307810378},
+ {3109170497657341517, 17179338146382046416, 10757457188650866858, 6777926602245453235},
+ },
+ {
+ {5861627228365499618, 5011684805137210454, 1579621475012951778, 11535371650014354624},
+ {12847902922833318241, 4997014846790385136, 9875988184618650628, 13094082946822736823},
+ },
+ {
+ {2372542806512167707, 4770713673953713652, 14348746494327256696, 7497346441434630132},
+ {8937635379675246570, 8485257033326447249, 9021969910533595955, 17083952234675640995},
+ },
+ {
+ {15253158548483712314, 10967825792345015198, 9742716807127259344, 14359543366972625129},
+ {6622650705673586588, 10738437674137632549, 1628663686364470696, 6788821495127737255},
+ },
+ {
+ {10456049238997614164, 3762844951386993276, 489305084297229810, 1360312650067674972},
+ {11869321173985817492, 5817931657599210177, 16741327479242559412, 1205037582258757668},
+ },
+ },
+ {
+ {
+ {7109145612337154341, 10502845970727626855, 6527587047878193251, 7049690136888681718},
+ {16750703006415156202, 2559311261501721445, 1222802194566919230, 18019462938525560766},
+ },
+ {
+ {2592184418896595488, 1723751460114310463, 11198512454461769811, 6203707848404803677},
+ {2601731234271436477, 18186700975610533226, 4757569424831899615, 13359873383138312209},
+ },
+ {
+ {13904640252203718708, 10747313134117021792, 14667070697514384141, 2600977347774743546},
+ {15498986940124021079, 14740645313274577011, 17403811028932224808, 8060102076475954685},
+ },
+ {
+ {12990649636107730851, 13002224935892458030, 4380799638612122791, 7935443787987894924},
+ {10438069978940053126, 302419699431148366, 551508078777729872, 366155636877501719},
+ },
+ {
+ {14734735764746786753, 1378251478826083755, 13509550209468602124, 14458158239096821346},
+ {5681313138148713219, 9054039627425609375, 4235536482830620712, 1502753755874778370},
+ },
+ {
+ {8914021876030553161, 9071747156187788379, 14974736924255494885, 17070198435868341999},
+ {3643991391224035758, 260637732328275649, 17609644917816078225, 2302996326941944665},
+ },
+ {
+ {5888744936142942064, 17277140802638358763, 10290028650289820825, 1940657436863195045},
+ {10796401239257150661, 7788083050548605852, 13474393003015663489, 8961936186303685357},
+ },
+ {
+ {16407225233842256953, 13423683834633513951, 17454464203550700633, 6033758555290610449},
+ {5063673994339442907, 12250392784929419939, 5954485814444410119, 10099095370725442279},
+ },
+ {
+ {4687621216548073298, 12683256962895584277, 1406415612737291460, 3991320149877222007},
+ {403384179417053146, 7072351635192146705, 14388831570324308780, 2518546598792352745},
+ },
+ {
+ {2866701220158780648, 14345701180700655413, 10383205903323525163, 14561034237887346332},
+ {4525630512028460468, 7470042867870921036, 12498636959757093905, 14959680069767374094},
+ },
+ {
+ {939355076355747784, 236998652239230884, 7862332576114728232, 3008745396212765985},
+ {16892515157128448879, 1688671543548974140, 582235491724828261, 2879861045707356356},
+ },
+ {
+ {5793581539270397654, 12067972155882240315, 1914416028486337582, 2044052608129533771},
+ {1045680055817519578, 6183307954634642810, 1115903654002488241, 9729229622559998051},
+ },
+ {
+ {11505233554542243613, 13650372171621554098, 11886401428750724176, 2616122636264787282},
+ {9807875738265530891, 2065326856613209663, 3841177149705795822, 12478836916087572836},
+ },
+ {
+ {8725096612265348131, 16959754534248500306, 3934616751368449170, 887912345061829880},
+ {11410178859948957868, 12867384504930748729, 4367798270196663137, 4359910421693489126},
+ },
+ {
+ {18221589825782480868, 15875305463032670629, 1054133002549446970, 2220911650204683784},
+ {10874691797030180071, 13903803155513130100, 14873882741737344436, 9374498718172057556},
+ },
+ },
+ {
+ {
+ {4471613312912718060, 13601785177495103328, 8083849806888905297, 9053545412554844461},
+ {1876605639999952155, 6124537911475118673, 16877891074567085688, 16541720065079132344},
+ },
+ {
+ {18138305348849897995, 11498878557125400853, 14125346336359365201, 11991638807788804369},
+ {13935355764550912568, 16209147067155729660, 11086190285777019292, 16727288863943596410},
+ },
+ {
+ {8873152377611229668, 6260821826956744083, 11489383533808918262, 6585112195310961861},
+ {7365821041919648819, 1936165695028211587, 16164747634991415711, 17957320776652490392},
+ },
+ {
+ {13065030057172289846, 7278765836407486850, 383827150208081081, 7832055893191054601},
+ {5249323286889945617, 1631661912887095912, 4431088469837785451, 2866263172993336891},
+ },
+ {
+ {6140213328062333551, 16704025329777067037, 5839832043209342792, 9196354634862869885},
+ {2735762290983671190, 5323501742548818139, 3199127466610501482, 6719610946615763192},
+ },
+ {
+ {4032564124345275293, 240208626666701335, 10264845378648897042, 15608289126091352415},
+ {17866864241918154829, 6207477318890336372, 491708931325462670, 7002400618323099260},
+ },
+ {
+ {11507747783030541234, 13683043390668171754, 9924966309328785763, 5549516466627385909},
+ {3724001483041449858, 2408778220985427590, 10510707601023430105, 12862520912519186496},
+ },
+ {
+ {5012372868660694231, 12033652755433827667, 5960732801180177919, 6089487525155575261},
+ {18400192045204062277, 12754175136438960528, 6170965736016609163, 10141374482047067946},
+ },
+ {
+ {11781193922347227447, 16937876011211881637, 2982972111293427964, 1728244726890919596},
+ {3327997232304084768, 4754833121145407334, 5871027825507908591, 15772493911709624273},
+ },
+ {
+ {5862944033912881884, 11132730978666088350, 12167180155548291888, 16449838286695349787},
+ {14399676610730016345, 17071083123672650337, 13727728787831175379, 7507765123422748291},
+ },
+ {
+ {4883057314704644529, 6606742732149784343, 16070555141087563722, 8408294891669305261},
+ {4298316003054547788, 1573237855902568238, 5357176885445018289, 5855732582172939202},
+ },
+ {
+ {11721126538980357625, 7216004194033429913, 12765889884935948315, 6003399149613653734},
+ {4571046290325663920, 15023470461830485075, 11463513436288928362, 16135217522406374542},
+ },
+ {
+ {14300855104129153291, 11491527690078786162, 5674183453812271017, 5044682546652747711},
+ {9153978680942338831, 400454762074409409, 12351470849648616331, 10559229320903248832},
+ },
+ {
+ {11839166519633311143, 16489041153719856002, 4820713204385149226, 13768001962143023630},
+ {13107713406478328396, 15471245828032402460, 6733652296473831544, 7665657127090105428},
+ },
+ {
+ {6114372925011600760, 13061069979571997963, 12156991017966837826, 12403009591138383583},
+ {5761958709898299258, 1907771304051897263, 3007439379929412593, 18410854883912163962},
+ },
+ },
+ {
+ {
+ {10153847769616409178, 16591913677701651064, 11369151065084080884, 9493662847124813178},
+ {14299126668179023903, 2451525064998641745, 16055696673728703463, 7600736037142850105},
+ },
+ {
+ {3339871688614476269, 2937156932445032796, 2071344655111136329, 509603454456841298},
+ {10929109734329673813, 4531629375826317764, 1802431569220697099, 7971315018970882891},
+ },
+ {
+ {831440329504272059, 17398063681351066636, 14954668702259408996, 5717183520144440084},
+ {5683898996859918421, 9613688159291425744, 14476049487507222229, 3689544236835488368},
+ },
+ {
+ {4307546666223047416, 13914498777427309061, 6812156124789414732, 1680174913762530491},
+ {6756325174405757110, 2535144759174364990, 11263393915003278429, 14767595249676286403},
+ },
+ {
+ {16671897597823309975, 8846923580617118936, 16420413907022376284, 2344779928765541883},
+ {13727655669851883280, 934227091954463432, 4722713881950047653, 11812583008287470589},
+ },
+ {
+ {5321392406277114518, 347488367118035707, 13877286915167943316, 9829617275563347891},
+ {12220860524024630629, 12190721936758412489, 7308208895364574537, 1525158119497637419},
+ },
+ {
+ {12984508126047021344, 13884472939864196037, 7382834581395586970, 11638480609720520178},
+ {3822030693056621440, 16565826187005934945, 8411123762207988382, 1177726217844912325},
+ },
+ {
+ {6981289090623415465, 8930069945493884157, 8223216504978132408, 796477795300774057},
+ {3120155459209743472, 14825603392456550470, 3711879425019804830, 11041054473536223927},
+ },
+ {
+ {6533202055887887500, 8435346764005128028, 14910943752455571727, 12906760590440667071},
+ {6009159206340842586, 15232286290711710102, 13101554303130256987, 9535887764075322183},
+ },
+ {
+ {2364828287094520952, 12465747625792776806, 2520175043973011525, 17224593222741233568},
+ {1891958595100476046, 14167979679885431508, 6587293950576996181, 438078840840804918},
+ },
+ {
+ {3740623254035318453, 2026091438664349886, 10842473205058238690, 5471257179527938221},
+ {7725900701946760330, 2830662433803069280, 17799722315873409980, 10759084277615005300},
+ },
+ {
+ {14135544350792474553, 6171419888118563156, 12495035851387242130, 2843310747449412555},
+ {5668766087526340552, 10117858698838396246, 5181027414039980750, 13247490124270426},
+ },
+ {
+ {5630566354382744149, 13019515676216329576, 5170054423571001981, 6980215251505169036},
+ {12147009277250683724, 5685374899516102781, 10470553909247052379, 13479624060240397189},
+ },
+ {
+ {9352291669847160009, 8941401423217216209, 14488820078509299610, 16185610851702419585},
+ {11995025321082820298, 8447817180287020945, 5861763576711981236, 14278368152612939946},
+ },
+ {
+ {17266177108677586607, 54295173557875478, 6565771227548453510, 11327083086584790599},
+ {2516266639353612660, 16450448808532150212, 4693041555468884719, 10262468795248362309},
+ },
+ },
+ {
+ {
+ {2365455792963674834, 2249234228455309648, 5237136544555745182, 8814246419234451463},
+ {13017813702607013347, 2241193992640629733, 17982226236989862510, 9800528153239873634},
+ },
+ {
+ {17271890190678399664, 284117971978206043, 14999643475704678808, 6264699496666119083},
+ {8859934981351804429, 8300880062060532031, 3667839168820458685, 17133003164910522197},
+ },
+ {
+ {17791633957402883820, 5938849497629314459, 8356801465373786047, 3163889445599730677},
+ {9723709910898285412, 2841967670768995554, 10896757438566636700, 7434996874241771203},
+ },
+ {
+ {14086272070125896854, 12009239107306499026, 6592816798466831203, 11371087141421707743},
+ {16277593907837607793, 16449564916599232060, 17471042072158213549, 11953382410698485455},
+ },
+ {
+ {14613304240735929191, 7658770973133328064, 3028731168325633068, 1486737152001467114},
+ {16715835021406106944, 15214200823642287507, 18441898204110447697, 5669963154424393607},
+ },
+ {
+ {8381651800836461905, 275661552864412688, 5548629401959193001, 7174991431295718071},
+ {7441251258233899268, 14052832476485122412, 301250917807487282, 17797202428295526090},
+ },
+ {
+ {16448089571044203401, 1396460397790470601, 9796571033221459545, 8162511506983092708},
+ {13893406727199803081, 16188892369453405032, 16023105002157964343, 7061289566170423383},
+ },
+ {
+ {8743817608749172620, 7804846024944300667, 507107926259802795, 5258061329638283805},
+ {15071070675288472598, 1848743106176521296, 16295570828486620412, 7409462376590083349},
+ },
+ {
+ {2825832734356158434, 10662490421734807455, 6363563030616301959, 16552149102037287266},
+ {8852342875874616869, 16848248230809388411, 6581680050166700198, 245046966305064563},
+ },
+ {
+ {7828655274510399422, 8354801505584011854, 17818478328917068523, 17325245990806811268},
+ {750899848242404370, 6729023687199559366, 5406329621088392947, 9196565205678366888},
+ },
+ {
+ {8064539304829538257, 6441901327220658696, 17278408443193767018, 6094106832683864460},
+ {9824329910822370076, 5272517980512991724, 8211352561755619726, 16303987070546290759},
+ },
+ {
+ {16798983177239698753, 12189491924433050580, 9517619110936281609, 17570406314312177597},
+ {9873809692789257777, 7539953961664846819, 14652839873293130968, 11082914471633564328},
+ },
+ {
+ {5471221015674785794, 8844747884377425274, 10084666525179707178, 11340747033059217003},
+ {7295797213045550755, 8395678759725657352, 9654316500807954493, 9062353099996695484},
+ },
+ {
+ {4588282548354659427, 7317148840331807496, 1344326657487996813, 1542409176821028318},
+ {16178223850158437787, 14916858636047869579, 13512744779273961596, 13549205429423761570},
+ },
+ {
+ {12307321769285447055, 293357554223804370, 1007020265087773203, 701738899338647839},
+ {12276634770118212432, 14777553112070534726, 4541693432120405052, 9103025487888313415},
+ },
+ },
+ {
+ {
+ {5757832545805155636, 17609080533053427627, 13855662030602089892, 9622498683452213297},
+ {12281586442064581946, 610529441714948581, 14740357477019436626, 16983190111725558863},
+ },
+ {
+ {8470173855499872166, 15915210069852758660, 12368087246231545517, 3867174158581293223},
+ {9082358201271846042, 16663463402757176964, 13740908859955866819, 7748969412274962298},
+ },
+ {
+ {13375424826931892789, 8508645806391261552, 18359272328758476903, 16433208398005282080},
+ {13071423254987294580, 7999383023651164492, 14514701556577587750, 4848295889377673720},
+ },
+ {
+ {1020519568493754982, 10467781020270669620, 17607771250627508499, 6620300538436640218},
+ {3858527175523168333, 13798129597334232823, 12495322651937391008, 3926713306087152023},
+ },
+ {
+ {5116038770086590715, 9943789276328255827, 13715439407309914230, 4887040860130243503},
+ {18288477612078228131, 7640050573721350378, 14537362862524718973, 1658575506924200900},
+ },
+ {
+ {18400486168653423966, 18026904540891591040, 2037921821724043966, 18010956304511658647},
+ {3751340308708032971, 16275459031633957091, 17177866831427164840, 1635431811339422016},
+ },
+ {
+ {3897330996014812355, 14347736534650088376, 16862404119462964612, 12216005411754788835},
+ {11561909516001453735, 6261639657930189859, 9101978764314050064, 12280333151331067982},
+ },
+ {
+ {910276569977357717, 2872810615152156462, 1942106118995935911, 8734004121981822024},
+ {13862118436432879698, 1912639548162720505, 13060137938875924732, 10642216911059510120},
+ },
+ {
+ {5132232031613377471, 3053931945527415993, 2695169719602504430, 11855046366025891084},
+ {16462491222215366712, 16664416596202206835, 3077124688577987843, 7109495326459366311},
+ },
+ {
+ {3858762384693274897, 7520194928987242278, 4496744297661574884, 16159343214247089321},
+ {6441167128044578145, 3604951495694157848, 3072075325567814428, 1964798869371174506},
+ },
+ {
+ {13689578474000942304, 8998724267038772595, 3350174507425430811, 15015413657749135511},
+ {4848907595494161497, 7935644131326131098, 385849363817229511, 10087353746314516691},
+ },
+ {
+ {6067717601858189468, 10438404859927821308, 9991403870358837471, 17728358586134467771},
+ {13476949968946830198, 7311235997042381570, 4429835371823736972, 17463216455983091974},
+ },
+ {
+ {3446799583712077997, 6763499387263152328, 9231082163128267527, 7733182914440272884},
+ {17225092062157610409, 8163842076250628108, 14230171836718858439, 8195740716303697476},
+ },
+ {
+ {57759226194841354, 14962480748390190557, 2047254208877381876, 2830450574091058648},
+ {14905486147404440754, 15792397930637469157, 16383409053580142957, 8686506861607761226},
+ },
+ {
+ {11120178572139812895, 11534611317577597022, 10437856602660752754, 13925966850017814278},
+ {16776862023867799947, 17362554889424346260, 3408825299914455645, 2606150045870067742},
+ },
+ },
+ {
+ {
+ {12109367644744157376, 18037756988516427980, 814572839386760074, 913616818805172815},
+ {12974490864633240943, 5228203788953366069, 11458421156905635350, 14534725545904442520},
+ },
+ {
+ {13918155529832261002, 12953608416498491778, 4285102780598248527, 15853935066983430239},
+ {2610351403194505517, 14905969693015035277, 12043976761492019990, 3883507340167876094},
+ },
+ {
+ {5439519346074792827, 2176389624009388617, 2631244572392601375, 15049241095214776941},
+ {16292195309463965431, 4379169091046493311, 2454237863606964835, 16333960950959567989},
+ },
+ {
+ {10994470105201067642, 16033352651464686189, 15774427704233149170, 4596106024708523955},
+ {8854068685612048031, 13529126595187822090, 11509928293490788309, 11620850709434334690},
+ },
+ {
+ {267621988570094461, 10587206279243947181, 11593510291287574067, 14787400314862354894},
+ {4136983718443464652, 2976380359687256413, 11142324903811863489, 4610908641771667701},
+ },
+ {
+ {296274281547444433, 3085587185113256560, 12609265193181717917, 4535801536028989527},
+ {3096496338675531142, 9292526016029159200, 13112825412047135381, 16663099831183411702},
+ },
+ {
+ {2767353193349225715, 8712112934471091092, 608599382922156785, 4028449356066786979},
+ {17542394472389324402, 8680897831809226389, 7666317335732585298, 17261030852301003617},
+ },
+ {
+ {2068337952936280662, 6856444059219131741, 17213926210819196459, 513413453513211652},
+ {5520465604253824995, 12970886588014924605, 12296275668437451137, 16808287251356954962},
+ },
+ {
+ {15914937173048753781, 12510295026185206015, 15954705664179129326, 9689253582699600268},
+ {15356442010394775998, 2438265211465631320, 15141425278420483672, 17026865278332658671},
+ },
+ {
+ {775118291486058191, 14811108570252044526, 1277462327112210144, 1303109520734915949},
+ {17662756477349124684, 3447822852149651619, 6150341860560710757, 13223916277431807977},
+ },
+ {
+ {9324118164416603919, 86833914568469678, 16815316898277944489, 5015780480822908208},
+ {4077581079810359659, 6644887514971920354, 4892606269782662646, 12780428915404556278},
+ },
+ {
+ {3413637388791433603, 16937929882486384885, 11215805046681294327, 11559398419268924015},
+ {11697258172757450737, 6137795229387768085, 3190984692021653574, 15347236891154706739},
+ },
+ {
+ {12504195828868930633, 14311735968635225029, 3580069346315758668, 12909891866007218579},
+ {10780120525711488015, 17942431687417272891, 4966616543136223651, 11565637729828595342},
+ },
+ {
+ {12013939709036934636, 4233656138400235608, 5744753585886244254, 7800398410233442143},
+ {15609887409465530711, 11633197710359969914, 4221051249637072360, 11317958694020095179},
+ },
+ {
+ {5703670472856822602, 8043375474958283103, 2470834322231268196, 13020386017071254236},
+ {13795230438353673114, 9108571599173545401, 10145331563807416240, 17474439008571566321},
+ },
+ },
+ {
+ {
+ {16430555432520738762, 11225321696360643709, 11777973654353154098, 13133115227828884393},
+ {17678738157022850345, 1586660156856830642, 840647763693221003, 8645742354464326466},
+ },
+ {
+ {3598736754916501501, 4827022662021197854, 8203180748141933720, 10283251600632599041},
+ {16186680658340956808, 15183393398087319142, 8714402370450665212, 13217902016653171217},
+ },
+ {
+ {11743016372336018414, 6125536020759642301, 16563280170798047733, 14529052521060111789},
+ {15253502329174644388, 1556763737841306861, 3041940064290508531, 18020881359462953336},
+ },
+ {
+ {2297585344913389180, 13965959247788377604, 11341378863608387800, 9890953382689640379},
+ {10443523266835246852, 9631856696811288063, 6944503116553031744, 10030824122780966395},
+ },
+ {
+ {6636244234467769744, 18284390012667441869, 722929822219329257, 3274166388651987221},
+ {13177791837760949480, 2568122970128111127, 3477167651270374316, 11371867850093288299},
+ },
+ {
+ {12876460969864886954, 4692925517843901006, 17390372170975588763, 14692578774429957295},
+ {1759864963511373267, 12016553435172103063, 13015881292003590351, 16187569590073958370},
+ },
+ {
+ {5868176722765418764, 8429364877332796959, 7785756492654137899, 14975349488807886278},
+ {3272010964035218775, 8946396491617515063, 3774503492701710541, 2113917870331282160},
+ },
+ {
+ {13276631120161396750, 16968574704982977753, 2376454925072971568, 9477134218094425043},
+ {13784622991820528988, 2074505569780291922, 14294803056569335889, 8759684036994631222},
+ },
+ {
+ {9884417819806228161, 10473583853313294601, 14339795822328931094, 8504498283323826917},
+ {526127293629665058, 10891388783681447537, 4568472708151557518, 10369081088106148862},
+ },
+ {
+ {14875690099724520068, 15708131372860771936, 15063351920655636623, 13673754555867312132},
+ {15920462627529593070, 9885706734937065436, 16823591115242423655, 1258777215756511827},
+ },
+ {
+ {8202515950988182345, 14546423651242108828, 14227698061016162353, 10918615690964448766},
+ {17106085332738434415, 16355746637376756806, 990444867181428081, 15553043817355146246},
+ },
+ {
+ {3823475181283510630, 10848691050793796395, 6491636971888772243, 757676231362735550},
+ {8973136455980928416, 6503381298194573307, 7834237673135397878, 10787325521157907075},
+ },
+ {
+ {455211601892268020, 1552688795129565862, 8165081519906588268, 5446810663215253742},
+ {6750786745561416995, 6997284811902307211, 16012972729607911414, 9114458230677816387},
+ },
+ {
+ {10975008541567105079, 3750365577590028809, 13516995106985748006, 8919511738051569176},
+ {12930984911878205493, 14293252788401143455, 1989517604536428154, 10167748824687611261},
+ },
+ {
+ {4403033949751056724, 8371165401092074176, 4457099049748166877, 18160854660487137945},
+ {18090711188318162626, 2052332783995780991, 10990843822512572670, 8096670640545581193},
+ },
+ },
+ {
+ {
+ {987127652983079722, 6872208513691823695, 10110578719299008714, 16457381243184327116},
+ {10779072738879347999, 5965282398006505989, 18251577267494363268, 9321323379108563422},
+ },
+ {
+ {6119049170407437179, 12938407708038792521, 10105420405825346383, 3416306788177016826},
+ {330648587825212481, 125568991290568141, 13857127346570918649, 4376080986981308805},
+ },
+ {
+ {5930434126597036589, 11240994623469578584, 839346533006694594, 10015087329724081709},
+ {6285097815938761787, 17244606485954860090, 11523249727882012981, 7178451948850151803},
+ },
+ {
+ {16733615335426327004, 14833564736134873977, 15736159435317472941, 17560193966711884894},
+ {4670172300306758374, 9477713670983496835, 14243955354032737980, 6459864769649694970},
+ },
+ {
+ {16053517698989562256, 2069464650596796670, 18305730134729303993, 1090863611964008044},
+ {10595928817546105363, 11743183506441120484, 8584767248013363683, 9187452830514379903},
+ },
+ {
+ {6938579711827578880, 16268282168771714072, 4567473305742437221, 754548046014059669},
+ {7773636946295303572, 8132380485366854656, 5054542590195827722, 6074347500754248128},
+ },
+ {
+ {3955857908381474930, 11852678900999621852, 13783017203403417097, 13616745777931267488},
+ {13189924588414196918, 14519927295809952876, 9334100965942760501, 15172548734242885286},
+ },
+ {
+ {4869852132020793901, 14921212823114724347, 14342559113353033349, 13336827701782657309},
+ {11168346789878684452, 9790480725902426052, 9171116079841529936, 9268902731763220711},
+ },
+ {
+ {4417372365016540659, 17280138652899703220, 6650972319709075180, 11252221422799491438},
+ {6825784270383052414, 18308562203755695191, 4237445205082731447, 8485872406483449772},
+ },
+ {
+ {11718726714045105993, 2624508790343569765, 5794111482300008213, 12819216567095091385},
+ {285329842793152354, 17257707863943097374, 16912487373614458842, 9501952033607497057},
+ },
+ {
+ {13074643344738491288, 8505193022029238118, 9932652098552590323, 267408114280737600},
+ {14802861246220332716, 17506028737327736269, 15929083591675282371, 10937680132245212187},
+ },
+ {
+ {16688733766460131050, 12777635326299184071, 7769405825716531061, 12435979606514844725},
+ {2767987141420672349, 6723940414217341603, 16114182069580717377, 4541113259200434040},
+ },
+ {
+ {8506371389960537559, 18031198550689409305, 11510251852995503442, 1923472385053944821},
+ {6189904387119195613, 345664413118550356, 6439003191582953600, 18344385760549575361},
+ },
+ {
+ {5320548958745018096, 8341561189829530680, 3327828110998403156, 17981346269177513223},
+ {14254804273025688074, 11111147827704077234, 9093333670517437191, 7272552282364063165},
+ },
+ {
+ {7587268797387514088, 4402481408866840263, 11260815389095334885, 14391444701764948710},
+ {4224880318604689771, 2472148458660279030, 961218007313548745, 13826356220879831691},
+ },
+ },
+ {
+ {
+ {5733697799130763963, 962857090393715865, 10538932452511329419, 3413281437172590207},
+ {6635428480179771287, 4404718679994229138, 329074170931436370, 17746708206910902139},
+ },
+ {
+ {179238781994802586, 9017860544212172426, 16179187983079961859, 1380105261896053495},
+ {6187003332254463653, 9896593306091975718, 17181949235068293496, 6820143159816507763},
+ },
+ {
+ {4652378169433586070, 2069013165869224423, 13972912433480425078, 2248203233787863058},
+ {12819880125496785064, 12462800229583867169, 7969192387226362512, 15450728326339004590},
+ },
+ {
+ {11156900805411912784, 1737275748212365168, 16993486692205800040, 12538938066475152524},
+ {13167476167764338790, 17373319366642541595, 6054831428930905282, 7118452124011953000},
+ },
+ {
+ {15319323094268250368, 15751569639563379275, 9174762389399453601, 5359273060607997116},
+ {7548480167962649047, 4093535200286790152, 18255003581953064302, 17037929372197430710},
+ },
+ {
+ {3640693116491518731, 9689920283410066894, 16070225083132083168, 13505008973802466003},
+ {750230942699692016, 15522838682331888368, 112268476925002814, 17491605970126192984},
+ },
+ {
+ {16769567946241955549, 17099752525969374817, 14041401861628609700, 13883170585376164878},
+ {1568639950869924595, 7305902646691031157, 12536573783075304502, 12490145094151973568},
+ },
+ {
+ {743288751022377974, 9226164090128370715, 17669221687181604232, 1117842260351396541},
+ {17697784451833850722, 14382209306891991103, 16951372733687268016, 188390802712613066},
+ },
+ {
+ {7332583781810119624, 11974900502289827649, 9825039434151224666, 13612433455140779130},
+ {11167094757836568968, 148858902984029622, 4325547061862811500, 8439987427904092212},
+ },
+ {
+ {9775040802880336170, 2183956155792599391, 10102475962557589963, 14902149990037881859},
+ {7528893974593517583, 18271333130592009124, 11812759747597590978, 3931581515688264350},
+ },
+ {
+ {7368734173241076742, 12419301291748626639, 10534790951032501149, 16676926058266807225},
+ {13614593066288445663, 5547469267128540754, 5071513241190976074, 6206141439571986364},
+ },
+ {
+ {13268209255833199938, 16633146482265079265, 6044233937395578074, 1733872861371247406},
+ {14239198956565602758, 4036306057099495106, 1778912298053970082, 6174082695927204648},
+ },
+ {
+ {9563897475320169888, 3828463449263891363, 4522408683909966848, 10085044841903958270},
+ {15115863363467748291, 3921763467143122522, 3241611744432406503, 16149166019569794702},
+ },
+ {
+ {13355027832202142668, 13259310595418810737, 16638224598838046396, 388655643128437049},
+ {6131988039969669992, 16758867465997134050, 793705445085763779, 16225736542798627427},
+ },
+ {
+ {12060616483613851492, 11185023117529741833, 15286366164051065546, 5407795227432242447},
+ {3261413161331398298, 7182873809282605970, 2155509494582452911, 16998725707829879258},
+ },
+ },
+ {
+ {
+ {14380343880230315251, 6834909096379668102, 15975839936772635678, 7738230945027714388},
+ {7971648870467745046, 8320128435052726628, 10820026056424631461, 7058118462476293754},
+ },
+ {
+ {11165438517321289842, 8661037418831619311, 4401480924846865713, 9355650368902126256},
+ {14352422544185763829, 12268031594529744663, 17607497268577344783, 12698954426769962214},
+ },
+ {
+ {5091534986326281709, 8005812102849517353, 17366496686564185717, 3658878980438307796},
+ {8455810244524637026, 7649393961871195909, 8629386422022530934, 507133797409068858},
+ },
+ {
+ {10098955144981013765, 4095621933458866623, 313357785962326778, 14880249056209398407},
+ {10605627454111004262, 7841561005378789988, 5015399193497762029, 5818383539901203899},
+ },
+ {
+ {829322392873083372, 3459913121476606612, 4547714508342797986, 5801286056105229312},
+ {11591136160675314269, 17965845487226778560, 7022309609363885527, 5990586084398664157},
+ },
+ {
+ {6288277991521986035, 12231480617236286340, 8633990423689180869, 13535190275290488690},
+ {13419223868164389899, 17622732596713666209, 10071779220640400024, 9451660464882303005},
+ },
+ {
+ {11761084765182152401, 9226969173242076459, 5445719591917489914, 9371133174853825566},
+ {18381867235964583187, 17262888224001222346, 1934253649802391267, 3574888052111089863},
+ },
+ {
+ {15270079546607712667, 8471883658965202468, 10333206241569264742, 7414741159725097798},
+ {7709713706668701850, 4461310100162632915, 10099194304024685274, 4760203118683828795},
+ },
+ {
+ {784143359277603248, 15514589681861498400, 4131024411374659852, 3624433493936743696},
+ {3251402229976672212, 4649659622203715244, 926933500763282104, 6444675794782453444},
+ },
+ {
+ {3756269038539504739, 7020323719189662644, 9035687928909659722, 10611580746254894906},
+ {6310976205075048332, 11776014447017145895, 18193543588427463707, 12941703752632419110},
+ },
+ {
+ {13258346207952257162, 14737306929596267614, 139896257833059475, 5049568122463438631},
+ {12260461320589066027, 46497756452454082, 15185750105748824007, 3681406295924007900},
+ },
+ {
+ {2833339165549332500, 18300762432878821923, 13251805801497937312, 17798840894981774941},
+ {10659715417364364943, 9241413425866019176, 9144746556705463526, 18018473193185776281},
+ },
+ {
+ {7436336871105679313, 3718902224813103412, 8186181643677715434, 17182578567975462342},
+ {659724975715028710, 9425698860660002856, 796351253238186633, 18323943433898241577},
+ },
+ {
+ {13500588337778130334, 15143039800006025480, 5471884014140775766, 8599189774825271733},
+ {14063442714998210193, 17130659899212878144, 2181888550891204616, 13594088124987533554},
+ },
+ {
+ {16216101853436910766, 13302132899821289315, 8876723129840557561, 2026846371223185778},
+ {7753254296964005427, 16607365864296868674, 1800351426181020953, 12473523172043936884},
+ },
+ },
+ {
+ {
+ {14734199666349771791, 4159865781008764547, 4413963548436270853, 4489431649937855880},
+ {2824856157476907519, 5111945927271461159, 9825486821405155220, 7657332565522279292},
+ },
+ {
+ {8798422177670065832, 1250388939918922012, 5145324733132743026, 3716299737175574168},
+ {14387202892738514375, 10255681359895407489, 8563822744122397080, 18430417713920116013},
+ },
+ {
+ {7857399215288147901, 2593284350589299949, 10086687882410147351, 14407837835956327624},
+ {4469878646287387405, 6845712208092605310, 3019047164798827279, 2760591274816994522},
+ },
+ {
+ {10930605176025081830, 5850835312463207607, 9603163404664606781, 15623771803942139684},
+ {4096748595672894276, 13060617166821837740, 11222939712741281346, 18445178894593253710},
+ },
+ {
+ {7976335583419810431, 16568954524837045521, 5581116346602990350, 18369129318179031997},
+ {1930478946186473631, 14255806344323769850, 5302512325798050097, 10008570767203424472},
+ },
+ {
+ {929118050943456183, 445163760697913504, 7208246135487165437, 13565354217377841149},
+ {3835063466770003968, 8214155842021576753, 2078717035803259674, 12502657820500987763},
+ },
+ {
+ {17741004372977419914, 16320851348541958575, 11853008901690968430, 9954777341381304447},
+ {14274892887030297417, 10721339848307167540, 8731332510371325649, 13676383433520290197},
+ },
+ {
+ {6251805914672095769, 1063060143452094078, 16647397170554915088, 15454955736319919321},
+ {11509235104607349098, 8441647766544589978, 956121464218389431, 10752793912033728149},
+ },
+ {
+ {14879603883666664508, 11158422912437249402, 8667988090392051507, 12702057193823135575},
+ {13234479167199208223, 13752955092077643608, 1117550756888145931, 1184967682872965330},
+ },
+ {
+ {7004802666964716824, 395433501626287206, 16674151908279399004, 2279551165611331131},
+ {18032555740803644790, 3573953642384243989, 9892480504006025100, 2397759375236735831},
+ },
+ {
+ {15032723931727013905, 4176673226777913017, 7270920367565154969, 8867675920919464620},
+ {8174119413251699506, 15030539680120439131, 12325981936900309518, 2932283844656871802},
+ },
+ {
+ {3227890727136855788, 10772277744280338071, 10065219931092397730, 17233706446636791341},
+ {1372997838851103811, 14430098741859995846, 3290287064497023581, 13054133915521430696},
+ },
+ {
+ {3404625123065318735, 11884832674715736469, 16513753127836546671, 2355202492840722899},
+ {2182039060332057784, 17942518439766613327, 16731345075928062112, 5501869092504492134},
+ },
+ {
+ {15704211025163561149, 14596679078416770266, 10262177146233936833, 12443005669252298316},
+ {1541294166390346144, 2952804996209068760, 15358481016273272880, 1321729586231860999},
+ },
+ {
+ {6862865331233391228, 15106279167311639122, 3283008666555627541, 13405610967904725343},
+ {9845239597399801983, 10764942720093673542, 6506992344666983370, 2483131164245259278},
+ },
+ },
+ {
+ {
+ {9844707592410952215, 8167497709587672711, 18115463401502884199, 8471563375691441535},
+ {17525405040226359165, 2460181803833371342, 3375780580907171205, 3024376384135966552},
+ },
+ {
+ {18138724984190926809, 4154767406604950048, 5209478936276366634, 15469512148904762872},
+ {3613429290324777670, 12631812917445459751, 10280179062385049041, 19656860716268566},
+ },
+ {
+ {14203862032167128161, 13470939927320077756, 10327441827790615277, 10318573137694660185},
+ {14560780313347476436, 17088464982837309355, 733937949060316950, 14069325810788446179},
+ },
+ {
+ {12030193727051241373, 13981191132445467472, 18205169646206905593, 12162181194046583886},
+ {10929925499200074058, 15291772758590352491, 8452344520852919320, 8199821440451878776},
+ },
+ {
+ {702956275289752726, 11856189935311796245, 14185745521831658392, 4370665693013677718},
+ {4339320942948136612, 7422618440224759582, 871840009976682819, 1758213746931263134},
+ },
+ {
+ {7463305936638691553, 10552402742907536443, 9732741351132553899, 194397927117005699},
+ {12837197785265289115, 4412933472643099429, 12440864981406580998, 17072316007921211511},
+ },
+ {
+ {5025653014579399483, 6266285559889618786, 17667439302823084142, 8837073500207072384},
+ {16230880878690171580, 8966359704103918073, 2671625161783975934, 5761959268140569579},
+ },
+ {
+ {9876482463501409337, 17331045017548147052, 17542726936580732548, 8299195336372136083},
+ {12891767721269002608, 14062358772374813347, 4165127680073507756, 16350672737379495431},
+ },
+ {
+ {15987859092221739938, 10999006767011320329, 16931834873460681704, 40989027820989117},
+ {16439290771012023473, 6900965556474667785, 7253680936177336810, 17240235510851599487},
+ },
+ {
+ {4114449005477323279, 11333071244606712260, 5639227616302034307, 15107257128889549417},
+ {5046122977641767311, 17558812465185003134, 18137671581165086239, 4382776603153058089},
+ },
+ {
+ {18024760665596162063, 4581156045659391508, 968287218068232238, 9228777525067749703},
+ {17309990917327276325, 7114941925430814300, 16735731670154258613, 6290532662018771504},
+ },
+ {
+ {7595271959296927018, 15286771623821390629, 980612661413312852, 5738158184597378995},
+ {6972117550390447038, 6246497134979772260, 2935831443692029059, 12837371529160496660},
+ },
+ {
+ {10790135298802805255, 7259368218310211690, 12050916808246223984, 2030323364779525994},
+ {12824594050397534312, 4098150364864727064, 15604500991562385767, 2831443658783115116},
+ },
+ {
+ {6469454686530052235, 2594644969515545140, 5284951626835069400, 14441180041267617906},
+ {16001664398759990060, 13049178223054879255, 3268931999230968043, 3072360434503949622},
+ },
+ {
+ {4565530397071857053, 857029374864691712, 15955478286869670604, 17781316921869181573},
+ {16457191703043818907, 5989113593649065091, 4425872606756635499, 4532030700973621003},
+ },
+ },
+ {
+ {
+ {2317249352525369754, 15030797481081533168, 12237590576308284360, 15660076992611440873},
+ {11341015819700735887, 8280257602754365719, 9212501234696283343, 9673375202141178099},
+ },
+ {
+ {9762534010701623728, 15349113802811029024, 8305297169667044246, 18013018210154476198},
+ {18414050009163335761, 2190126859433916996, 5444481274452218807, 13415988647365667724},
+ },
+ {
+ {11641532224340210206, 71261001011952801, 2321745415903209397, 6595984444855093239},
+ {10341299657770272718, 11529878689049370930, 14381510695605158203, 6869272773579747365},
+ },
+ {
+ {1073778278665127828, 301289653767944933, 11482324780950168317, 10626716202328004967},
+ {7258024014655363102, 12597648090458567878, 2617914106162603499, 12324652644266476584},
+ },
+ {
+ {13957732574177025801, 1100344278733481546, 12156946932617203965, 2007756425747006287},
+ {16454508610548016441, 18058668363064769203, 15619001054652658323, 1201476243910931863},
+ },
+ {
+ {16341334571424533804, 4657494880554316004, 18092783076286521475, 19832895869027143},
+ {8667365497283429486, 11501953273367138162, 5832487631687776985, 664754160781757174},
+ },
+ {
+ {13524719886605363170, 11553593166914861649, 12034020205580665813, 985175984881624722},
+ {11040631342644137311, 12107496606245418129, 7328748654066365904, 14741972847454326011},
+ },
+ {
+ {12828567388121500364, 2264959796189127526, 6222205589523394088, 8827682270015065013},
+ {2619170858745203321, 14835030117099398518, 5960028394532808010, 2233397097850889639},
+ },
+ {
+ {3879642723354138203, 5439355518658448857, 14194463322012776543, 14947367699252203702},
+ {11497182458118153903, 16347396442451668378, 16912659817226286851, 6972297461053626970},
+ },
+ {
+ {14953681219966965709, 18116944572750863844, 16774540053916392198, 6518998682436778354},
+ {11207035159486725904, 17279266785091386830, 15987732680339874714, 4953887381255790681},
+ },
+ {
+ {18128055290529398111, 4838636144867908799, 17655818333374840693, 5013823741985131317},
+ {1920449774281311783, 13898340137609808546, 861099289958274037, 12441596565887895930},
+ },
+ {
+ {7244015348755525626, 13520825180887535513, 9165067445392785660, 9250553550156732893},
+ {15663564389384259196, 5724018088820370997, 11379531752316746866, 17687565409319417941},
+ },
+ {
+ {11050714794366707475, 12230144450501707996, 12363862313107363407, 6348205119671766380},
+ {14263471584626838352, 7350100163762375926, 1902788311165167298, 11691126042005505984},
+ },
+ {
+ {3948847772791576201, 11933738159609952054, 15749315384347059669, 8831922078851474178},
+ {8463496071867925621, 12756218686011120865, 4691766390469398064, 5252134452066688477},
+ },
+ {
+ {4880806069791899809, 11099088460364672063, 12627384861893315861, 4239079797011518662},
+ {14560690935803003234, 15267325636353169132, 16919582304973803583, 10073876067858458517},
+ },
+ },
+ {
+ {
+ {15695265447782578013, 15506558718447241194, 12341861439298989232, 18400958156300100845},
+ {13704811286967591150, 5802260047239067846, 3266013253411255445, 9892957742319181954},
+ },
+ {
+ {6053458788987550519, 3243549259991905443, 17990025476026266205, 3918149716414968130},
+ {562225565996136148, 12175287017902713154, 16317970834262634990, 5431198806775607012},
+ },
+ {
+ {15123186170178367264, 3054913246068400920, 8130663466272395280, 2852812622149318730},
+ {6747630551931917110, 18302049774259156971, 3663865061939346221, 12340091610704678811},
+ },
+ {
+ {17453312277789785069, 1148609799196055657, 5931758962926317381, 5297597381576544508},
+ {9136842287749269744, 3007653173299649609, 12364677607049679091, 3656932227466449489},
+ },
+ {
+ {17732801126130995365, 16093023291975796560, 17028512234142609413, 6293028118993952199},
+ {4019599708379609715, 3557632583507755601, 16737140015288442165, 7041678499288317736},
+ },
+ {
+ {5187842645752673199, 14914432544387315508, 4944360914161982641, 4177329533692612281},
+ {18423887817846407126, 11935898134550505219, 9191754399457615042, 962223885189306707},
+ },
+ {
+ {5467152559317256227, 13407023128339380091, 656806207084558176, 10823228592509573890},
+ {282802378108427873, 13003319652664166176, 11501612671901244594, 8595770155487539951},
+ },
+ {
+ {1805255869285898834, 11676967700876044626, 3486630203654875772, 8366336693945605431},
+ {17874084888474647879, 8803709150655606891, 680993178667234696, 1603785777136148315},
+ },
+ {
+ {3637712241808318043, 1673622542455477465, 14468899013751477571, 6607241816357171779},
+ {2332200248940843815, 14077155355848738174, 17298155509321457563, 13624623885136011130},
+ },
+ {
+ {12550073596584561722, 13898852145577133829, 31360866049197404, 12629522544897401454},
+ {4563446134761510332, 7272813487383198495, 16767195814334178362, 13600498026689482359},
+ },
+ {
+ {5170414136067325373, 10875290278133558518, 7331268231382198947, 4082234313337835514},
+ {11725295114019619895, 6488017511603508543, 11399466652931338200, 2898113599278666684},
+ },
+ {
+ {7553418756944942759, 2324485560009697358, 16004009784734101843, 8345371056076551939},
+ {7377284629098981027, 11049718262343754276, 8021605820736410979, 8175349759714152494},
+ },
+ {
+ {805625092558946929, 11996029844853502332, 1725029464967101849, 8189609560660709539},
+ {10396089572662865065, 1756007811373736605, 7645529329516777410, 2608132938055260111},
+ },
+ {
+ {17014595621244604813, 1574499958190108567, 8684546755761322906, 9997538531915911005},
+ {5652402150243592363, 6315865356369667235, 8687115108443972047, 12369176255146729475},
+ },
+ {
+ {5117004045853299762, 2238407612548002914, 12392667457861900490, 10614312910576266709},
+ {6446577503758597410, 3767883614425995197, 17954966454260719539, 5233322901463099},
+ },
+ },
+ {
+ {
+ {1081257522368061155, 16144982029632101790, 2280210790959566458, 5000326950136078873},
+ {10441086845859171982, 5717080014740953823, 16816253740467637151, 5185838557034755093},
+ },
+ {
+ {3897734650128449985, 3892478283047854402, 153850176068596076, 4448963435449755938},
+ {9911011406822436713, 6379744721342779297, 360324666931028426, 8002086405015565067},
+ },
+ {
+ {13662666854424521459, 17028614494600252018, 13372166182804100759, 8978661571842967509},
+ {1689945315009228820, 9997133634912151808, 4070075534875432478, 5780712439158341418},
+ },
+ {
+ {18068291112584812890, 10288580446655316879, 16866690514199445805, 15458664010538199871},
+ {17175925202246173890, 12208778610361755998, 927739404697616036, 10330183209424493139},
+ },
+ {
+ {4422872630455196261, 14815650254807917367, 9426346157598724768, 17764302665164113296},
+ {9474027272970951461, 3048886202121388617, 7073604597785890399, 9516006646305083675},
+ },
+ {
+ {16541317581647968302, 7221753201217091047, 554497992080233562, 12743131795939254731},
+ {6113032707000257613, 4448176364247161206, 738044254484725063, 3096942233684051465},
+ },
+ {
+ {2801392933730991479, 15502003900939246745, 11340323610824656109, 13690394827169426680},
+ {2298413291804124677, 12243772219106809119, 9550327342593445260, 18354548835264437008},
+ },
+ {
+ {17095781462759061506, 13984950766342782369, 7038608479806172868, 7073471193601880894},
+ {9212126909381119712, 15865851343492198107, 3874039137971369196, 15366505242302572319},
+ },
+ {
+ {10476508037395688256, 5905562397524931472, 15147896444621280595, 3856601647293477321},
+ {4204909177546012159, 17515684210872904454, 12561834979880779760, 6477848309789627185},
+ },
+ {
+ {3226022509034031128, 5771385963704757771, 17861700165696478115, 14976034400726774156},
+ {17945959497662269352, 6322288130414861016, 3008853024335853994, 5599925939427067989},
+ },
+ {
+ {15408448007738805625, 3855259080280453396, 11776434265478354726, 11784885919111239520},
+ {8108981861486003291, 16553896039002150783, 5694423121092647200, 16414563259092889693},
+ },
+ {
+ {3235058267792568155, 8030551941244615429, 12851363585510555514, 9786973022560471711},
+ {4901414898060251968, 13240438628487941170, 4707852389766057435, 6503805666511566831},
+ },
+ {
+ {1178073204986944698, 10685133932326477495, 11710162005310407793, 11019188929725710305},
+ {16244991946372165706, 3272168887117805467, 15045747299972144833, 8155681972478369649},
+ },
+ {
+ {12308450869393289693, 14268794937571237354, 9141189178824378983, 11605207657904000518},
+ {17071770108549330148, 11045960524457021256, 13807710432855107212, 8427718050873363613},
+ },
+ {
+ {16762196363426636910, 7316863360113205703, 7937998445095491508, 3946557199536080470},
+ {16019910399697645039, 11522845950519380293, 2362453023191035102, 6547077716792082654},
+ },
+ },
+ {
+ {
+ {5218985848865375996, 5835476376320976237, 9096499658845542933, 8952489298840360492},
+ {16605895184424459659, 505731104315931813, 17784248872812610986, 4151555707609374291},
+ },
+ {
+ {4963953120977916566, 6585250545846301109, 4490972754776862709, 10674499592300479120},
+ {17494988318349821345, 1814042777264686189, 8938395423478059768, 9062966010283426056},
+ },
+ {
+ {3879469818714011415, 11493820457829716643, 10091807027724827301, 5032134849078736052},
+ {18015749204009276046, 9667758283246223357, 4629693773460610802, 3807196436109718946},
+ },
+ {
+ {5724217930909760221, 15420221591912350415, 9910465013739250802, 12511683773790779491},
+ {2841532862707547306, 16614426471009646589, 407574220261191228, 17422057170120224031},
+ },
+ {
+ {3725101809714764432, 2995111022132376824, 9338883729618021504, 8824923738291347476},
+ {3745497072215538317, 3576446898425965872, 2350077748663612773, 15793255155885543355},
+ },
+ {
+ {12904339001067417585, 1972265247859388742, 8908590936681392405, 10320719400504224158},
+ {8298368064038407143, 2105745729886511647, 16509751074757847095, 15156289751671616565},
+ },
+ {
+ {885617946245226760, 17871561572095909264, 16413308527330544768, 2938750343525834336},
+ {6332736376778563648, 16772687696658236231, 9760470695949399178, 17420556823805232882},
+ },
+ {
+ {4407657041250297528, 13832960959347315977, 15056546959967740939, 4350443362134191429},
+ {8013419913016572733, 8888684099801298477, 15401479253620745715, 18279947201669400847},
+ },
+ {
+ {16774767206504477529, 15784248755460218800, 890363416232172440, 6798249980336291014},
+ {1295939576916968887, 14501516576359061383, 5181286196215569291, 8884842683907072200},
+ },
+ {
+ {12906144535917740163, 4179201185048577793, 8949647323841299627, 2168773816567792706},
+ {1715683170634778607, 9901501903322086192, 7624633731287546358, 10530124063631858009},
+ },
+ {
+ {14199956317346734484, 13250211595320054421, 18197952479293091552, 16161313407818957084},
+ {17435507292968186894, 6560268436714668609, 1299607057816966726, 8157462320016248727},
+ },
+ {
+ {3603583288706717651, 17387128326071547512, 17907604816622771553, 17853094381965037384},
+ {12273843852205811233, 13840584476006398280, 2018654168596055410, 11549248055135584644},
+ },
+ {
+ {4742377140579111706, 845465928037625085, 12028953960657292824, 16438644767032965255},
+ {17377088622232632294, 1631558517096568450, 11363064014018667511, 6006029335296807862},
+ },
+ {
+ {8877393780281438935, 9848923171251074575, 1554975198005028643, 2251034043951525516},
+ {9696558687758873050, 3889942916226212472, 8326933892612496812, 7463785348361544799},
+ },
+ {
+ {4205364996189816688, 5453611962777060261, 16993840011943171053, 11689161310506207011},
+ {16699173739044458906, 6254168288000491517, 12642281218300963313, 10028950653175051753},
+ },
+ },
+ {
+ {
+ {8784043285714375740, 8483257759279461889, 8789745728267363600, 1770019616739251654},
+ {15992936863339206154, 10037038012062884956, 15197544864945402661, 9615747158586711429},
+ },
+ {
+ {9583737883674400333, 12279877754802111101, 8296198976379850969, 17778859909846088251},
+ {3401986641240187301, 1525831644595056632, 1849003687033449918, 8702493044913179195},
+ },
+ {
+ {18423170064697770279, 12693387071620743675, 7398701556189346968, 2779682216903406718},
+ {12703629940499916779, 6358598532389273114, 8683512038509439374, 15415938252666293255},
+ },
+ {
+ {8408419572923862476, 5066733120953500019, 926242532005776114, 6301489109130024811},
+ {3285079390283344806, 1685054835664548935, 7740622190510199342, 9561507292862134371},
+ },
+ {
+ {13698695174800826869, 10442832251048252285, 10672604962207744524, 14485711676978308040},
+ {16947216143812808464, 8342189264337602603, 3837253281927274344, 8331789856935110934},
+ },
+ {
+ {4627808394696681034, 6174000022702321214, 15351247319787348909, 1371147458593240691},
+ {10651965436787680331, 2998319090323362997, 17592419471314886417, 11874181791118522207},
+ },
+ {
+ {524165018444839759, 3157588572894920951, 17599692088379947784, 1421537803477597699},
+ {2902517390503550285, 7440776657136679901, 17263207614729765269, 16928425260420958311},
+ },
+ {
+ {2878166099891431311, 5056053391262430293, 10345032411278802027, 13214556496570163981},
+ {17698482058276194679, 2441850938900527637, 1314061001345252336, 6263402014353842038},
+ },
+ {
+ {8487436533858443496, 12386798851261442113, 3224748875345095424, 16166568617729909099},
+ {2213369110503306004, 6246347469485852131, 3129440554298978074, 605269941184323483},
+ },
+ {
+ {3177531230451277512, 11022989490494865721, 8321856985295555401, 14727273563873821327},
+ {876865438755954294, 14139765236890058248, 6880705719513638354, 8678887646434118325},
+ },
+ {
+ {16896703203004244996, 11377226897030111200, 2302364246994590389, 4499255394192625779},
+ {1906858144627445384, 2670515414718439880, 868537809054295101, 7535366755622172814},
+ },
+ {
+ {339769604981749608, 12384581172556225075, 2596838235904096350, 5684069910326796630},
+ {913125548148611907, 1661497269948077623, 2892028918424825190, 9220412792897768138},
+ },
+ {
+ {14754959387565938441, 1023838193204581133, 13599978343236540433, 8323909593307920217},
+ {3852032956982813055, 7526785533690696419, 8993798556223495105, 18140648187477079959},
+ },
+ {
+ {11692087196810962506, 1328079167955601379, 1664008958165329504, 18063501818261063470},
+ {2861243404839114859, 13702578580056324034, 16781565866279299035, 1524194541633674171},
+ },
+ {
+ {8267721299596412251, 273633183929630283, 17164190306640434032, 16332882679719778825},
+ {4663567915067622493, 15521151801790569253, 7273215397645141911, 2324445691280731636},
+ },
+ },
+ }
+}
diff --git a/core/crypto/_weierstrass/tools/ecc_gen_tables.odin b/core/crypto/_weierstrass/tools/ecc_gen_tables.odin
new file mode 100644
index 000000000..e69927a90
--- /dev/null
+++ b/core/crypto/_weierstrass/tools/ecc_gen_tables.odin
@@ -0,0 +1,99 @@
+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_p256r1_tables()
+}
+
+gen_p256r1_tables :: proc() {
+ Affine_Point_p256r1 :: struct {
+ x: secec.Field_Element_p256r1,
+ y: secec.Field_Element_p256r1,
+ }
+ Multiply_Table_p256r1_hi: [32][15]Affine_Point_p256r1
+ Multiply_Table_p256r1_lo: [32][15]Affine_Point_p256r1
+
+ g, p: secec.Point_p256r1
+ secec.pt_generator(&g)
+
+ // Precompute ([1,15] << n) * G multiples of G, MSB->LSB
+ for i in 0..<32 {
+ b: [32]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_p256r1_hi[i][j-1].x, &p.x)
+ secec.fe_set(&Multiply_Table_p256r1_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_p256r1_lo[i][j-1].x, &p.x)
+ secec.fe_set(&Multiply_Table_p256r1_lo[i][j-1].y, &p.y)
+
+ b[i] = 0
+ }
+ }
+
+ fn := path.join({ODIN_ROOT, "core", "crypto", "_weierstrass", "secp256r1_table.odin"})
+ 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.wprintln(w, "\tGen_Multiply_Table_p256r1_hi := [32][15]Affine_Point_p256r1 {")
+ for &v, i in Multiply_Table_p256r1_hi {
+ fmt.wprintln(w, "\t\t{")
+ for &ap, j in v {
+ fmt.wprintln(w, "\t\t\t{")
+
+ x, y := &ap.x, &ap.y
+ 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])
+
+ fmt.wprintln(w, "\t\t\t},")
+ }
+ fmt.wprintln(w, "\t\t},")
+ }
+ fmt.wprintln(w, "\t}\n")
+
+ fmt.wprintln(w, "\t@(private,rodata)")
+ fmt.wprintln(w, "\tGen_Multiply_Table_p256r1_lo := [32][15]Affine_Point_p256r1 {")
+ for &v, i in Multiply_Table_p256r1_lo {
+ fmt.wprintln(w, "\t\t{")
+ for &ap, j in v {
+ fmt.wprintln(w, "\t\t\t{")
+
+ x, y := &ap.x, &ap.y
+ 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])
+
+ 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)))
+}
diff --git a/core/crypto/crypto.odin b/core/crypto/crypto.odin
index 7ccf126e6..3fb369a54 100644
--- a/core/crypto/crypto.odin
+++ b/core/crypto/crypto.odin
@@ -2,8 +2,12 @@
package crypto
import "base:runtime"
+import subtle "core:crypto/_subtle"
import "core:mem"
+// Omit large precomputed tables, trading off performance for size.
+COMPACT_IMPLS: bool : #config(ODIN_CRYPTO_COMPACT, false)
+
// HAS_RAND_BYTES is true iff the runtime provides a cryptographic
// entropy source.
HAS_RAND_BYTES :: runtime.HAS_RAND_BYTES
@@ -44,7 +48,17 @@ compare_byte_ptrs_constant_time :: proc "contextless" (a, b: ^byte, n: int) -> i
// After the loop, v == 0 iff a == b. The subtraction will underflow
// iff v == 0, setting the sign-bit, which gets returned.
- return int((u32(v)-1) >> 31)
+ return subtle.eq(0, v)
+}
+
+// is_zero_constant_time returns 1 iff b is all 0s, 0 otherwise.
+is_zero_constant_time :: proc "contextless" (b: []byte) -> int {
+ v: byte
+ for b_ in b {
+ v |= b_
+ }
+
+ return subtle.byte_eq(0, v)
}
// rand_bytes fills the dst buffer with cryptographic entropy taken from
diff --git a/core/crypto/ecdh/doc.odin b/core/crypto/ecdh/doc.odin
new file mode 100644
index 000000000..e34f255f2
--- /dev/null
+++ b/core/crypto/ecdh/doc.odin
@@ -0,0 +1,4 @@
+/*
+A generic interface to Elliptic Curve Diffie-Hellman key exchange.
+*/
+package ecdh
diff --git a/core/crypto/ecdh/ecdh.odin b/core/crypto/ecdh/ecdh.odin
new file mode 100644
index 000000000..3e97ebdc7
--- /dev/null
+++ b/core/crypto/ecdh/ecdh.odin
@@ -0,0 +1,404 @@
+package ecdh
+
+import "core:crypto"
+import secec "core:crypto/_weierstrass"
+import "core:crypto/x25519"
+import "core:crypto/x448"
+import "core:mem"
+import "core:reflect"
+
+// Note: For these primitives scalar size = point size
+@(private="file")
+X25519_Buf :: [x25519.SCALAR_SIZE]byte
+@(private="file")
+X448_Buf :: [x448.SCALAR_SIZE]byte
+
+// Curve the curve identifier associated with a given Private_Key
+// or Public_Key
+Curve :: enum {
+ Invalid,
+ SECP256R1,
+ X25519,
+ X448,
+}
+
+// CURVE_NAMES is the Curve to curve name string.
+CURVE_NAMES := [Curve]string {
+ .Invalid = "Invalid",
+ .SECP256R1 = "secp256r1",
+ .X25519 = "X25519",
+ .X448 = "X448",
+}
+
+// PRIVATE_KEY_SIZES is the Curve to private key size in bytes.
+PRIVATE_KEY_SIZES := [Curve]int {
+ .Invalid = 0,
+ .SECP256R1 = secec.SC_SIZE_P256R1,
+ .X25519 = x25519.SCALAR_SIZE,
+ .X448 = x448.SCALAR_SIZE,
+}
+
+// PUBLIC_KEY_SIZES is the Curve to public key size in bytes.
+PUBLIC_KEY_SIZES := [Curve]int {
+ .Invalid = 0,
+ .SECP256R1 = 1 + 2 * secec.FE_SIZE_P256R1,
+ .X25519 = x25519.POINT_SIZE,
+ .X448 = x448.POINT_SIZE,
+}
+
+// SHARED_SECRET_SIZES is the Curve to shared secret size in bytes.
+SHARED_SECRET_SIZES := [Curve]int {
+ .Invalid = 0,
+ .SECP256R1 = secec.FE_SIZE_P256R1,
+ .X25519 = x25519.POINT_SIZE,
+ .X448 = x448.POINT_SIZE,
+}
+
+@(private="file")
+_PRIV_IMPL_IDS := [Curve]typeid {
+ .Invalid = nil,
+ .SECP256R1 = typeid_of(secec.Scalar_p256r1),
+ .X25519 = typeid_of(X25519_Buf),
+ .X448 = typeid_of(X448_Buf),
+}
+
+@(private="file")
+_PUB_IMPL_IDS := [Curve]typeid {
+ .Invalid = nil,
+ .SECP256R1 = typeid_of(secec.Point_p256r1),
+ .X25519 = typeid_of(X25519_Buf),
+ .X448 = typeid_of(X448_Buf),
+}
+
+// Private_Key is an ECDH private key.
+Private_Key :: struct {
+ // WARNING: All of the members are to be treated as internal (ie:
+ // the Private_Key structure is intended to be opaque).
+ _curve: Curve,
+ _impl: union {
+ secec.Scalar_p256r1,
+ X25519_Buf,
+ X448_Buf,
+ },
+ _pub_key: Public_Key,
+}
+
+// Public_Key is an ECDH public key.
+Public_Key :: struct {
+ // WARNING: All of the members are to be treated as internal (ie:
+ // the Public_Key structure is intended to be opaque).
+ _curve: Curve,
+ _impl: union {
+ secec.Point_p256r1,
+ X25519_Buf,
+ X448_Buf,
+ },
+}
+
+// private_key_generate uses the system entropy source to generate a new
+// Private_Key. This will only fail iff the system entropy source is
+// missing or broken.
+private_key_generate :: proc(priv_key: ^Private_Key, curve: Curve) -> bool {
+ private_key_clear(priv_key)
+
+ if !crypto.HAS_RAND_BYTES {
+ return false
+ }
+
+ reflect.set_union_variant_typeid(
+ priv_key._impl,
+ _PRIV_IMPL_IDS[curve],
+ )
+
+ #partial switch curve {
+ case .SECP256R1:
+ sc := &priv_key._impl.(secec.Scalar_p256r1)
+
+ // 384-bits reduced makes the modulo bias insignificant
+ b: [48]byte = ---
+ defer (mem.zero_explicit(&b, size_of(b)))
+ for {
+ crypto.rand_bytes(b[:])
+ _ = secec.sc_set_bytes(sc, b[:])
+ if secec.sc_is_zero(sc) == 0 { // Likely
+ break
+ }
+ }
+ case .X25519:
+ sc := &priv_key._impl.(X25519_Buf)
+ crypto.rand_bytes(sc[:])
+ case .X448:
+ sc := &priv_key._impl.(X448_Buf)
+ crypto.rand_bytes(sc[:])
+ case:
+ panic("crypto/ecdh: invalid curve")
+ }
+
+ priv_key._curve = curve
+ private_key_generate_public(priv_key)
+
+ return true
+}
+
+// private_key_set_bytes decodes a byte-encoded private key, and returns
+// true iff the operation was successful.
+private_key_set_bytes :: proc(priv_key: ^Private_Key, curve: Curve, b: []byte) -> bool {
+ private_key_clear(priv_key)
+
+ if len(b) != PRIVATE_KEY_SIZES[curve] {
+ return false
+ }
+
+ reflect.set_union_variant_typeid(
+ priv_key._impl,
+ _PRIV_IMPL_IDS[curve],
+ )
+
+ #partial switch curve {
+ case .SECP256R1:
+ sc := &priv_key._impl.(secec.Scalar_p256r1)
+ did_reduce := secec.sc_set_bytes(sc, b)
+ is_zero := secec.sc_is_zero(sc) == 1
+
+ // Reject `0` and scalars that are not less than the
+ // curve order.
+ if did_reduce || is_zero {
+ private_key_clear(priv_key)
+ return false
+ }
+ case .X25519:
+ sc := &priv_key._impl.(X25519_Buf)
+ copy(sc[:], b)
+ case .X448:
+ sc := &priv_key._impl.(X448_Buf)
+ copy(sc[:], b)
+ case:
+ panic("crypto/ecdh: invalid curve")
+ }
+
+ priv_key._curve = curve
+ private_key_generate_public(priv_key)
+
+ return true
+}
+
+@(private="file")
+private_key_generate_public :: proc(priv_key: ^Private_Key) {
+ switch &sc in priv_key._impl {
+ case secec.Scalar_p256r1:
+ pub_key: secec.Point_p256r1 = ---
+ secec.pt_scalar_mul_generator(&pub_key, &sc)
+ secec.pt_rescale(&pub_key, &pub_key)
+ priv_key._pub_key._impl = pub_key
+ case X25519_Buf:
+ pub_key: X25519_Buf = ---
+ x25519.scalarmult_basepoint(pub_key[:], sc[:])
+ priv_key._pub_key._impl = pub_key
+ case X448_Buf:
+ pub_key: X448_Buf = ---
+ x448.scalarmult_basepoint(pub_key[:], sc[:])
+ priv_key._pub_key._impl = pub_key
+ case:
+ panic("crypto/ecdh: invalid curve")
+ }
+
+ priv_key._pub_key._curve = priv_key._curve
+}
+
+// private_key_bytes sets dst to byte-encoding of priv_key.
+private_key_bytes :: proc(priv_key: ^Private_Key, dst: []byte) {
+ ensure(priv_key._curve != .Invalid, "crypto/ecdh: uninitialized private key")
+ ensure(len(dst) == PRIVATE_KEY_SIZES[priv_key._curve], "crypto/ecdh: invalid destination size")
+
+ #partial switch priv_key._curve {
+ case .SECP256R1:
+ sc := &priv_key._impl.(secec.Scalar_p256r1)
+ secec.sc_bytes(dst, sc)
+ case .X25519:
+ sc := &priv_key._impl.(X25519_Buf)
+ copy(dst, sc[:])
+ case .X448:
+ sc := &priv_key._impl.(X448_Buf)
+ copy(dst, sc[:])
+ case:
+ panic("crypto/ecdh: invalid curve")
+ }
+}
+
+// private_key_equal returns true iff the private keys are equal,
+// in constant time.
+private_key_equal :: proc(p, q: ^Private_Key) -> bool {
+ if p._curve != q._curve {
+ return false
+ }
+
+ #partial switch p._curve {
+ case .SECP256R1:
+ sc_p, sc_q := &p._impl.(secec.Scalar_p256r1), &q._impl.(secec.Scalar_p256r1)
+ return secec.sc_equal(sc_p, sc_q) == 1
+ case .X25519:
+ b_p, b_q := &p._impl.(X25519_Buf), &q._impl.(X25519_Buf)
+ return crypto.compare_constant_time(b_p[:], b_q[:]) == 1
+ case .X448:
+ b_p, b_q := &p._impl.(X448_Buf), &q._impl.(X448_Buf)
+ return crypto.compare_constant_time(b_p[:], b_q[:]) == 1
+ case:
+ return false
+ }
+}
+
+// private_key_clear clears priv_key to the uninitialized state.
+private_key_clear :: proc "contextless" (priv_key: ^Private_Key) {
+ mem.zero_explicit(priv_key, size_of(Private_Key))
+}
+
+// public_key_set_bytes decodes a byte-encoded public key, and returns
+// true iff the operation was successful.
+public_key_set_bytes :: proc(pub_key: ^Public_Key, curve: Curve, b: []byte) -> bool {
+ public_key_clear(pub_key)
+
+ if len(b) != PUBLIC_KEY_SIZES[curve] {
+ return false
+ }
+
+ reflect.set_union_variant_typeid(
+ pub_key._impl,
+ _PUB_IMPL_IDS[curve],
+ )
+
+ #partial switch curve {
+ case .SECP256R1:
+ if b[0] != secec.SEC_PREFIX_UNCOMPRESSED {
+ return false
+ }
+
+ pt := &pub_key._impl.(secec.Point_p256r1)
+ ok := secec.pt_set_sec_bytes(pt, b)
+ if !ok || secec.pt_is_identity(pt) == 1 {
+ return false
+ }
+ case .X25519:
+ pt := &pub_key._impl.(X25519_Buf)
+ copy(pt[:], b)
+ case .X448:
+ pt := &pub_key._impl.(X448_Buf)
+ copy(pt[:], b)
+ case:
+ panic("crypto/ecdh: invalid curve")
+ }
+
+ pub_key._curve = curve
+
+ return true
+}
+
+// public_key_set_priv sets pub_key to the public component of priv_key.
+public_key_set_priv :: proc(pub_key: ^Public_Key, priv_key: ^Private_Key) {
+ ensure(priv_key._curve != .Invalid, "crypto/ecdh: uninitialized private key")
+ public_key_clear(pub_key)
+ pub_key^ = priv_key._pub_key
+}
+
+// public_key_bytes sets dst to byte-encoding of pub_key.
+public_key_bytes :: proc(pub_key: ^Public_Key, dst: []byte) {
+ ensure(pub_key._curve != .Invalid, "crypto/ecdh: uninitialized public key")
+ ensure(len(dst) == PUBLIC_KEY_SIZES[pub_key._curve], "crypto/ecdh: invalid destination size")
+
+ #partial switch pub_key._curve {
+ case .SECP256R1:
+ // Invariant: Unless the caller is manually building pub_key
+ // `Z = 1`, so we can skip the rescale.
+ pt := &pub_key._impl.(secec.Point_p256r1)
+
+ dst[0] = secec.SEC_PREFIX_UNCOMPRESSED
+ secec.fe_bytes(dst[1:1+secec.FE_SIZE_P256R1], &pt.x)
+ secec.fe_bytes(dst[1+secec.FE_SIZE_P256R1:], &pt.y)
+ case .X25519:
+ pt := &pub_key._impl.(X25519_Buf)
+ copy(dst, pt[:])
+ case .X448:
+ pt := &pub_key._impl.(X448_Buf)
+ copy(dst, pt[:])
+ case:
+ panic("crypto/ecdh: invalid curve")
+ }
+}
+
+// public_key_equal returns true iff the public keys are equal,
+// in constant time.
+public_key_equal :: proc(p, q: ^Public_Key) -> bool {
+ if p._curve != q._curve {
+ return false
+ }
+
+ #partial switch p._curve {
+ case .SECP256R1:
+ pt_p, pt_q := &p._impl.(secec.Point_p256r1), &q._impl.(secec.Point_p256r1)
+ return secec.pt_equal(pt_p, pt_q) == 1
+ case .X25519:
+ b_p, b_q := &p._impl.(X25519_Buf), &q._impl.(X25519_Buf)
+ return crypto.compare_constant_time(b_p[:], b_q[:]) == 1
+ case .X448:
+ b_p, b_q := &p._impl.(X448_Buf), &q._impl.(X448_Buf)
+ return crypto.compare_constant_time(b_p[:], b_q[:]) == 1
+ case:
+ panic("crypto/ecdh: invalid curve")
+ }
+}
+
+// public_key_clear clears pub_key to the uninitialized state.
+public_key_clear :: proc "contextless" (pub_key: ^Public_Key) {
+ mem.zero_explicit(pub_key, size_of(Public_Key))
+}
+
+// ecdh performs an Elliptic Curve Diffie-Hellman key exchange betwween
+// the Private_Key and Public_Key, writing the shared secret to dst.
+//
+// The neutral element is rejected as an error.
+@(require_results)
+ecdh :: proc(priv_key: ^Private_Key, pub_key: ^Public_Key, dst: []byte) -> bool {
+ ensure(priv_key._curve == pub_key._curve, "crypto/ecdh: curve mismatch")
+ ensure(pub_key._curve != .Invalid, "crypto/ecdh: uninitialized public key")
+ ensure(len(dst) == SHARED_SECRET_SIZES[priv_key._curve], "crypto/ecdh: invalid shared secret size")
+
+ #partial switch priv_key._curve {
+ case .SECP256R1:
+ sc, pt := &priv_key._impl.(secec.Scalar_p256r1), &pub_key._impl.(secec.Point_p256r1)
+ ss: secec.Point_p256r1
+ defer secec.pt_clear(&ss)
+
+ secec.pt_scalar_mul(&ss, pt, sc)
+ return secec.pt_bytes(dst, nil, &ss)
+ case .X25519:
+ sc, pt := &priv_key._impl.(X25519_Buf), &pub_key._impl.(X25519_Buf)
+ x25519.scalarmult(dst, sc[:], pt[:])
+ case .X448:
+ sc, pt := &priv_key._impl.(X448_Buf), &pub_key._impl.(X448_Buf)
+ x448.scalarmult(dst, sc[:], pt[:])
+ case:
+ panic("crypto/ecdh: invalid curve")
+ }
+
+ // X25519/X448 check for all zero digest.
+ return crypto.is_zero_constant_time(dst) == 0
+}
+
+// curve returns the Curve used by a Private_Key or Public_Key instance.
+curve :: proc(k: ^$T) -> Curve where(T == Private_Key || T == Public_Key) {
+ return k._curve
+}
+
+// key_size returns the key size of a Private_Key or Public_Key in bytes.
+key_size :: proc(k: ^$T) -> int where(T == Private_Key || T == Public_Key) {
+ when T == Private_Key {
+ return PRIVATE_KEY_SIZES[k._curve]
+ } else {
+ return PUBLIC_KEY_SIZES[k._curve]
+ }
+}
+
+// shared_secret_size returns the shared secret size of a key exchange
+// in bytes.
+shared_secret_size :: proc(k: ^$T) -> int where(T == Private_Key || T == Public_Key) {
+ return SHARED_SECRET_SIZES[k._curve]
+}
diff --git a/core/crypto/ed25519/ed25519.odin b/core/crypto/ed25519/ed25519.odin
index 0382a6739..f6a71d888 100644
--- a/core/crypto/ed25519/ed25519.odin
+++ b/core/crypto/ed25519/ed25519.odin
@@ -170,7 +170,7 @@ public_key_set_bytes :: proc "contextless" (pub_key: ^Public_Key, b: []byte) ->
// public_key_set_priv sets pub_key to the public component of priv_key.
public_key_set_priv :: proc(pub_key: ^Public_Key, priv_key: ^Private_Key) {
- ensure(priv_key._is_initialized, "crypto/ed25519: uninitialized public key")
+ ensure(priv_key._is_initialized, "crypto/ed25519: uninitialized private key")
src := &priv_key._pub_key
copy(pub_key._b[:], src._b[:])
diff --git a/core/crypto/x25519/x25519.odin b/core/crypto/x25519/x25519.odin
index e25d1831f..2d7aa4153 100644
--- a/core/crypto/x25519/x25519.odin
+++ b/core/crypto/x25519/x25519.odin
@@ -6,6 +6,8 @@ See:
*/
package x25519
+import "core:crypto"
+import ed "core:crypto/_edwards25519"
import field "core:crypto/_fiat/field_curve25519"
import "core:mem"
@@ -14,8 +16,10 @@ SCALAR_SIZE :: 32
// POINT_SIZE is the size of a X25519 point (public key/shared secret) in bytes.
POINT_SIZE :: 32
-@(private, rodata)
-_BASE_POINT: [32]byte = {9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+when crypto.COMPACT_IMPLS == true {
+ @(private,rodata)
+ _BASE_POINT: [32]byte = {9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+}
@(private)
_scalar_bit :: #force_inline proc "contextless" (s: ^[32]byte, i: int) -> u8 {
@@ -111,19 +115,44 @@ scalarmult :: proc(dst, scalar, point: []byte) {
e[31] &= 127
e[31] |= 64
- p: [32]byte = ---
- copy_slice(p[:], point)
-
- d: [32]byte = ---
- _scalarmult(&d, &e, &p)
- copy_slice(dst, d[:])
+ p := (^[32]byte)(raw_data(point))
+ d := (^[32]byte)(raw_data(dst))
+ _scalarmult(d, &e, p)
mem.zero_explicit(&e, size_of(e))
- mem.zero_explicit(&d, size_of(d))
}
// scalarmult_basepoint "multiplies" the provided scalar with the X25519
// base point and writes the resulting point to dst.
scalarmult_basepoint :: proc(dst, scalar: []byte) {
- scalarmult(dst, scalar, _BASE_POINT[:])
+ when crypto.COMPACT_IMPLS == true {
+ scalarmult(dst, scalar, _BASE_POINT[:])
+ } else {
+ ensure(len(scalar) == SCALAR_SIZE, "crypto/x25519: invalid scalar size")
+ ensure(len(dst) == POINT_SIZE, "crypto/x25519: invalid destination point size")
+
+ sc: ed.Scalar = ---
+ ed.sc_set_bytes_rfc8032(&sc, scalar)
+
+ ge: ed.Group_Element = ---
+ ed.ge_scalarmult_basepoint(&ge, &sc)
+
+ // u = (y + z)/(z - y)
+ y_plus_z: field.Loose_Field_Element = ---
+ z_minus_y: field.Loose_Field_Element = ---
+ u: field.Tight_Field_Element = ---
+
+ field.fe_add(&y_plus_z, &ge.y, &ge.z)
+ field.fe_sub(&z_minus_y, &ge.z, &ge.y)
+ field.fe_carry_inv(&u, &z_minus_y)
+ field.fe_carry_mul(&u, &y_plus_z, field.fe_relax_cast(&u))
+
+ dst_ := (^[32]byte)(raw_data(dst))
+ field.fe_to_bytes(dst_, &u)
+
+ field.fe_clear_vec([]^field.Loose_Field_Element{&y_plus_z, &z_minus_y})
+ field.fe_clear(&u)
+ ed.sc_clear(&sc)
+ ed.ge_clear(&ge)
+ }
}
diff --git a/core/odin/ast/ast.odin b/core/odin/ast/ast.odin
index 6755ca4d0..ec22db434 100644
--- a/core/odin/ast/ast.odin
+++ b/core/odin/ast/ast.odin
@@ -798,6 +798,7 @@ Struct_Type :: struct {
is_raw_union: bool,
is_no_copy: bool,
is_all_or_none: bool,
+ is_simple: bool,
fields: ^Field_List,
name_count: int,
}
diff --git a/core/odin/parser/parser.odin b/core/odin/parser/parser.odin
index 719cb0374..a18942e6b 100644
--- a/core/odin/parser/parser.odin
+++ b/core/odin/parser/parser.odin
@@ -2667,6 +2667,7 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
is_raw_union: bool
is_no_copy: bool
is_all_or_none: bool
+ is_simple: bool
fields: ^ast.Field_List
name_count: int
@@ -2695,6 +2696,11 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
error(p, tag.pos, "duplicate struct tag '#%s'", tag.text)
}
is_all_or_none = true
+ case "simple":
+ if is_simple {
+ error(p, tag.pos, "duplicate struct tag '#%s'", tag.text)
+ }
+ is_simple = true
case "align":
if align != nil {
error(p, tag.pos, "duplicate struct tag '#%s'", tag.text)
@@ -2769,6 +2775,7 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr {
st.is_raw_union = is_raw_union
st.is_no_copy = is_no_copy
st.is_all_or_none = is_all_or_none
+ st.is_simple = is_simple
st.fields = fields
st.name_count = name_count
st.where_token = where_token
diff --git a/core/os/os2/path_windows.odin b/core/os/os2/path_windows.odin
index 1225ab2ce..ce3828755 100644
--- a/core/os/os2/path_windows.odin
+++ b/core/os/os2/path_windows.odin
@@ -283,6 +283,10 @@ _is_absolute_path :: proc(path: string) -> bool {
if _is_reserved_name(path) {
return true
}
+ if len(path) > 0 && _is_path_separator(path[0]) {
+ return true
+ }
+
l := _volume_name_len(path)
if l == 0 {
return false
diff --git a/core/path/filepath/path.odin b/core/path/filepath/path.odin
index 14a9181c3..dbad98fa1 100644
--- a/core/path/filepath/path.odin
+++ b/core/path/filepath/path.odin
@@ -49,35 +49,66 @@ volume_name_len :: proc(path: string) -> int {
if len(path) < 2 {
return 0
}
- c := path[0]
+
if path[1] == ':' {
- switch c {
+ switch path[0] {
case 'a'..='z', 'A'..='Z':
return 2
}
}
- // URL: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx
- if l := len(path); l >= 5 && is_slash(path[0]) && is_slash(path[1]) &&
- !is_slash(path[2]) && path[2] != '.' {
- for n := 3; n < l-1; n += 1 {
- if is_slash(path[n]) {
- n += 1
- if !is_slash(path[n]) {
- if path[n] == '.' {
- break
- }
- }
- for ; n < l; n += 1 {
- if is_slash(path[n]) {
- break
- }
- }
- return n
+ /*
+ See: URL: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx
+ Further allowed paths can be of the form of:
+ - \\server\share or \\server\share\more\path
+ - \\?\C:\...
+ - \\.\PhysicalDriveX
+ */
+ // Any remaining kind of path has to start with two slashes.
+ if !is_separator(path[0]) || !is_separator(path[1]) {
+ return 0
+ }
+
+ // Device path. The volume name is the whole string
+ if len(path) >= 5 && path[2] == '.' && is_separator(path[3]) {
+ return len(path)
+ }
+
+ // We're a UNC share `\\host\share`, file namespace `\\?\C:` or UNC in file namespace `\\?\\host\share`
+ prefix := 2
+
+ // File namespace.
+ if len(path) >= 5 && path[2] == '?' && is_separator(path[3]) {
+ if is_separator(path[4]) {
+ // `\\?\\` UNC path in file namespace
+ prefix = 5
+ }
+
+ if len(path) >= 6 && path[5] == ':' {
+ switch path[4] {
+ case 'a'..='z', 'A'..='Z':
+ return 6
+ case:
+ return 0
}
- break
}
}
+
+ // UNC path, minimum version of the volume is `\\h\s` for host, share.
+ // Can also contain an IP address in the host position.
+ slash_count := 0
+ for i in prefix..<len(path) {
+ // Host needs to be at least 1 character
+ if is_separator(path[i]) && i > 0 {
+ slash_count += 1
+
+ if slash_count == 2 {
+ return i
+ }
+ }
+ }
+
+ return len(path)
}
return 0
}
@@ -368,8 +399,8 @@ rel :: proc(base_path, target_path: string, allocator := context.allocator) -> (
return strings.clone(".", allocator), .None
}
- base_vol := volume_name(base_path)
- target_vol := volume_name(target_path)
+ base_vol := volume_name(base_clean)
+ target_vol := volume_name(target_clean)
base := base_clean [len(base_vol):]
target := target_clean[len(target_vol):]
if base == "." {
diff --git a/core/path/filepath/path_windows.odin b/core/path/filepath/path_windows.odin
index b3f4eee9e..d7549a42c 100644
--- a/core/path/filepath/path_windows.odin
+++ b/core/path/filepath/path_windows.odin
@@ -36,6 +36,9 @@ is_abs :: proc(path: string) -> bool {
if is_reserved_name(path) {
return true
}
+ if len(path) > 0 && is_slash(path[0]) {
+ return true
+ }
l := volume_name_len(path)
if l == 0 {
return false
diff --git a/core/reflect/types.odin b/core/reflect/types.odin
index d6d7011d1..385edb19b 100644
--- a/core/reflect/types.odin
+++ b/core/reflect/types.odin
@@ -696,9 +696,10 @@ write_type_writer :: #force_no_inline proc(w: io.Writer, ti: ^Type_Info, n_writt
}
io.write_string(w, "struct ", &n) or_return
- if .packed in info.flags { io.write_string(w, "#packed ", &n) or_return }
- if .raw_union in info.flags { io.write_string(w, "#raw_union ", &n) or_return }
+ if .packed in info.flags { io.write_string(w, "#packed ", &n) or_return }
+ if .raw_union in info.flags { io.write_string(w, "#raw_union ", &n) or_return }
if .all_or_none in info.flags { io.write_string(w, "#all_or_none ", &n) or_return }
+ if .simple in info.flags { io.write_string(w, "#simple ", &n) or_return }
if .align in info.flags {
io.write_string(w, "#align(", &n) or_return
io.write_i64(w, i64(ti.align), 10, &n) or_return
diff --git a/core/unicode/utf8/utf8.odin b/core/unicode/utf8/utf8.odin
index 281e36f43..78cefa8b4 100644
--- a/core/unicode/utf8/utf8.odin
+++ b/core/unicode/utf8/utf8.odin
@@ -60,6 +60,7 @@ accept_sizes := [256]u8{
0xf5..=0xff = 0xf1, // ascii, size 1
}
+@(require_results)
encode_rune :: proc "contextless" (c: rune) -> ([4]u8, int) {
r := c
@@ -101,9 +102,11 @@ decode_rune :: proc{
decode_rune_in_string,
decode_rune_in_bytes,
}
+@(require_results)
decode_rune_in_string :: #force_inline proc "contextless" (s: string) -> (rune, int) {
return decode_rune_in_bytes(transmute([]u8)s)
}
+@(require_results)
decode_rune_in_bytes :: proc "contextless" (s: []u8) -> (rune, int) {
n := len(s)
if n < 1 {
@@ -141,6 +144,7 @@ decode_rune_in_bytes :: proc "contextless" (s: []u8) -> (rune, int) {
return rune(s0&MASK4)<<18 | rune(b1&MASKX)<<12 | rune(b2&MASKX)<<6 | rune(b3&MASKX), 4
}
+@(require_results)
string_to_runes :: proc "odin" (s: string, allocator := context.allocator) -> (runes: []rune) {
n := rune_count_in_string(s)
@@ -153,6 +157,7 @@ string_to_runes :: proc "odin" (s: string, allocator := context.allocator) -> (r
return
}
+@(require_results)
runes_to_string :: proc "odin" (runes: []rune, allocator := context.allocator) -> string {
byte_count := 0
for r in runes {
@@ -177,9 +182,11 @@ decode_last_rune :: proc{
decode_last_rune_in_bytes,
}
+@(require_results)
decode_last_rune_in_string :: #force_inline proc "contextless" (s: string) -> (rune, int) {
return decode_last_rune_in_bytes(transmute([]u8)s)
}
+@(require_results)
decode_last_rune_in_bytes :: proc "contextless" (s: []u8) -> (rune, int) {
r: rune
size: int
@@ -212,6 +219,7 @@ decode_last_rune_in_bytes :: proc "contextless" (s: []u8) -> (rune, int) {
return r, size
}
+@(require_results)
rune_at_pos :: proc "contextless" (s: string, pos: int) -> rune {
if pos < 0 {
return RUNE_ERROR
@@ -227,6 +235,7 @@ rune_at_pos :: proc "contextless" (s: string, pos: int) -> rune {
return RUNE_ERROR
}
+@(require_results)
rune_string_at_pos :: proc "contextless" (s: string, pos: int) -> string {
if pos < 0 {
return ""
@@ -243,6 +252,7 @@ rune_string_at_pos :: proc "contextless" (s: string, pos: int) -> string {
return ""
}
+@(require_results)
rune_at :: proc "contextless" (s: string, byte_index: int) -> rune {
r, _ := decode_rune_in_string(s[byte_index:])
return r
@@ -250,6 +260,7 @@ rune_at :: proc "contextless" (s: string, byte_index: int) -> rune {
// Returns the byte position of rune at position pos in s with an optional start byte position.
// Returns -1 if it runs out of the string.
+@(require_results)
rune_offset :: proc "contextless" (s: string, pos: int, start: int = 0) -> int {
if pos < 0 {
return -1
@@ -265,6 +276,7 @@ rune_offset :: proc "contextless" (s: string, pos: int, start: int = 0) -> int {
return -1
}
+@(require_results)
valid_rune :: proc "contextless" (r: rune) -> bool {
if r < 0 {
return false
@@ -276,6 +288,7 @@ valid_rune :: proc "contextless" (r: rune) -> bool {
return true
}
+@(require_results)
valid_string :: proc "contextless" (s: string) -> bool {
n := len(s)
for i := 0; i < n; {
@@ -309,6 +322,7 @@ valid_string :: proc "contextless" (s: string) -> bool {
return true
}
+@(require_results)
rune_start :: #force_inline proc "contextless" (b: u8) -> bool {
return b&0xc0 != 0x80
}
@@ -318,9 +332,11 @@ rune_count :: proc{
rune_count_in_bytes,
}
+@(require_results)
rune_count_in_string :: #force_inline proc(s: string) -> int {
return rune_count_in_bytes(transmute([]u8)s)
}
+@(require_results)
rune_count_in_bytes :: proc "contextless" (s: []u8) -> int {
count := 0
n := len(s)
@@ -360,6 +376,7 @@ rune_count_in_bytes :: proc "contextless" (s: []u8) -> int {
}
+@(require_results)
rune_size :: proc "contextless" (r: rune) -> int {
switch {
case r < 0: return -1
@@ -381,6 +398,7 @@ full_rune :: proc{
// full_rune_in_bytes reports if the bytes in b begin with a full utf-8 encoding of a rune or not
// An invalid encoding is considered a full rune since it will convert as an error rune of width 1 (RUNE_ERROR)
+@(require_results)
full_rune_in_bytes :: proc "contextless" (b: []byte) -> bool {
n := len(b)
if n == 0 {
@@ -401,6 +419,7 @@ full_rune_in_bytes :: proc "contextless" (b: []byte) -> bool {
// full_rune_in_string reports if the bytes in s begin with a full utf-8 encoding of a rune or not
// An invalid encoding is considered a full rune since it will convert as an error rune of width 1 (RUNE_ERROR)
+@(require_results)
full_rune_in_string :: proc "contextless" (s: string) -> bool {
return full_rune_in_bytes(transmute([]byte)s)
}
diff --git a/examples/all/all_js.odin b/examples/all/all_js.odin
index 28b85f537..ee006ae86 100644
--- a/examples/all/all_js.odin
+++ b/examples/all/all_js.odin
@@ -33,6 +33,7 @@ package all
@(require) import "core:crypto/chacha20poly1305"
@(require) import chash "core:crypto/hash"
@(require) import "core:crypto/deoxysii"
+@(require) import "core:crypto/ecdh"
@(require) import "core:crypto/ed25519"
@(require) import "core:crypto/hkdf"
@(require) import "core:crypto/hmac"
diff --git a/examples/all/all_main.odin b/examples/all/all_main.odin
index 9a7613ba5..c5f627653 100644
--- a/examples/all/all_main.odin
+++ b/examples/all/all_main.odin
@@ -17,13 +17,14 @@ package all
@(require) import "core:container/avl"
@(require) import "core:container/bit_array"
+@(require) import "core:container/handle_map"
+@(require) import "core:container/intrusive/list"
+@(require) import "core:container/lru"
@(require) import "core:container/pool"
@(require) import "core:container/priority_queue"
@(require) import "core:container/queue"
-@(require) import "core:container/small_array"
-@(require) import "core:container/lru"
-@(require) import "core:container/intrusive/list"
@(require) import "core:container/rbtree"
+@(require) import "core:container/small_array"
@(require) import "core:container/topological_sort"
@(require) import "core:container/xar"
@@ -37,6 +38,7 @@ package all
@(require) import "core:crypto/chacha20poly1305"
@(require) import chash "core:crypto/hash"
@(require) import "core:crypto/deoxysii"
+@(require) import "core:crypto/ecdh"
@(require) import "core:crypto/ed25519"
@(require) import "core:crypto/hkdf"
@(require) import "core:crypto/hmac"
diff --git a/src/check_expr.cpp b/src/check_expr.cpp
index 46455aacf..1c09ad908 100644
--- a/src/check_expr.cpp
+++ b/src/check_expr.cpp
@@ -4704,12 +4704,14 @@ gb_internal void convert_to_typed(CheckerContext *c, Operand *operand, Type *tar
switch (t->kind) {
case Type_Basic:
if (operand->mode == Addressing_Constant) {
- check_is_expressible(c, operand, t);
+ check_is_expressible(c, operand, target_type);
if (operand->mode == Addressing_Invalid) {
return;
}
update_untyped_expr_value(c, operand->expr, operand->value);
- } else {
+ }
+
+ {
switch (operand->type->Basic.kind) {
case Basic_UntypedBool:
if (!is_type_boolean(target_type)) {
@@ -12692,8 +12694,10 @@ gb_internal gbString write_expr_to_string(gbString str, Ast *node, bool shorthan
str = write_expr_to_string(str, st->polymorphic_params, shorthand);
str = gb_string_appendc(str, ") ");
}
- if (st->is_packed) str = gb_string_appendc(str, "#packed ");
- if (st->is_raw_union) str = gb_string_appendc(str, "#raw_union ");
+ if (st->is_packed) str = gb_string_appendc(str, "#packed ");
+ if (st->is_raw_union) str = gb_string_appendc(str, "#raw_union ");
+ if (st->is_all_or_none) str = gb_string_appendc(str, "#all_or_none ");
+ if (st->is_simple) str = gb_string_appendc(str, "#simple ");
if (st->align) {
str = gb_string_appendc(str, "#align ");
str = write_expr_to_string(str, st->align, shorthand);
diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp
index 835f0162a..2dc621a84 100644
--- a/src/check_stmt.cpp
+++ b/src/check_stmt.cpp
@@ -1027,7 +1027,9 @@ gb_internal void check_unroll_range_stmt(CheckerContext *ctx, Ast *node, u32 mod
error(operand.expr, "Cannot iterate over '%s' of type '%s' in an '#unroll for' statement", s, t);
gb_string_free(t);
gb_string_free(s);
- } else if (operand.mode != Addressing_Constant && unroll_count <= 0) {
+ } else if (operand.mode != Addressing_Constant && (
+ unroll_count <= 0 &&
+ compare_exact_values(Token_CmpEq, inline_for_depth, exact_value_i64(0)))) {
error(operand.expr, "An '#unroll for' expression must be known at compile time");
}
}
diff --git a/src/check_type.cpp b/src/check_type.cpp
index 4b8f7b6ac..41c5f48d1 100644
--- a/src/check_type.cpp
+++ b/src/check_type.cpp
@@ -679,6 +679,21 @@ gb_internal void check_struct_type(CheckerContext *ctx, Type *struct_type, Ast *
gb_unused(where_clause_ok);
}
check_struct_fields(ctx, node, &struct_type->Struct.fields, &struct_type->Struct.tags, st->fields, min_field_count, struct_type, context);
+
+ if (st->is_simple) {
+ bool success = true;
+ for (Entity *f : struct_type->Struct.fields) {
+ if (!is_type_nearly_simple_compare(f->type)) {
+ gbString s = type_to_string(f->type);
+ error(f->token, "'struct #simple' requires all fields to be at least 'nearly simple compare', got %s", s);
+ gb_string_free(s);
+ }
+ }
+ if (success) {
+ struct_type->Struct.is_simple = true;
+ }
+ }
+
wait_signal_set(&struct_type->Struct.fields_wait_signal);
}
diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp
index b3b5f4251..81755af2d 100644
--- a/src/llvm_backend_stmt.cpp
+++ b/src/llvm_backend_stmt.cpp
@@ -1434,12 +1434,13 @@ gb_internal void lb_build_unroll_range_stmt(lbProcedure *p, AstUnrollRangeStmt *
if (unroll_count_ev.kind == ExactValue_Invalid) {
- GB_ASSERT(expr->tav.mode == Addressing_Constant);
Type *t = base_type(expr->tav.type);
switch (t->kind) {
case Type_Basic:
+ GB_ASSERT(expr->tav.mode == Addressing_Constant);
+
GB_ASSERT(is_type_string(t));
{
ExactValue value = expr->tav.value;
diff --git a/src/parser.cpp b/src/parser.cpp
index 1f08eaec1..c14055275 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -1230,7 +1230,7 @@ gb_internal Ast *ast_dynamic_array_type(AstFile *f, Token token, Ast *elem) {
}
gb_internal Ast *ast_struct_type(AstFile *f, Token token, Slice<Ast *> fields, isize field_count,
- Ast *polymorphic_params, bool is_packed, bool is_raw_union, bool is_all_or_none,
+ Ast *polymorphic_params, bool is_packed, bool is_raw_union, bool is_all_or_none, bool is_simple,
Ast *align, Ast *min_field_align, Ast *max_field_align,
Token where_token, Array<Ast *> const &where_clauses) {
Ast *result = alloc_ast_node(f, Ast_StructType);
@@ -1241,6 +1241,7 @@ gb_internal Ast *ast_struct_type(AstFile *f, Token token, Slice<Ast *> fields, i
result->StructType.is_packed = is_packed;
result->StructType.is_raw_union = is_raw_union;
result->StructType.is_all_or_none = is_all_or_none;
+ result->StructType.is_simple = is_simple;
result->StructType.align = align;
result->StructType.min_field_align = min_field_align;
result->StructType.max_field_align = max_field_align;
@@ -2788,6 +2789,7 @@ gb_internal Ast *parse_operand(AstFile *f, bool lhs) {
bool is_packed = false;
bool is_all_or_none = false;
bool is_raw_union = false;
+ bool is_simple = false;
Ast *align = nullptr;
Ast *min_field_align = nullptr;
Ast *max_field_align = nullptr;
@@ -2869,11 +2871,16 @@ gb_internal Ast *parse_operand(AstFile *f, bool lhs) {
error_line("\tSuggestion: #max_field_align(%s)", s);
gb_string_free(s);
}
- }else if (tag.string == "raw_union") {
+ } else if (tag.string == "raw_union") {
if (is_raw_union) {
syntax_error(tag, "Duplicate struct tag '#%.*s'", LIT(tag.string));
}
is_raw_union = true;
+ } else if (tag.string == "simple") {
+ if (is_simple) {
+ syntax_error(tag, "Duplicate struct tag '#%.*s'", LIT(tag.string));
+ }
+ is_simple = true;
} else {
syntax_error(tag, "Invalid struct tag '#%.*s'", LIT(tag.string));
}
@@ -2919,7 +2926,7 @@ gb_internal Ast *parse_operand(AstFile *f, bool lhs) {
parser_check_polymorphic_record_parameters(f, polymorphic_params);
return ast_struct_type(f, token, decls, name_count,
- polymorphic_params, is_packed, is_raw_union, is_all_or_none,
+ polymorphic_params, is_packed, is_raw_union, is_all_or_none, is_simple,
align, min_field_align, max_field_align,
where_token, where_clauses);
} break;
diff --git a/src/parser.hpp b/src/parser.hpp
index 011330438..39f56ffae 100644
--- a/src/parser.hpp
+++ b/src/parser.hpp
@@ -780,6 +780,7 @@ AST_KIND(_TypeBegin, "", bool) \
bool is_raw_union; \
bool is_no_copy; \
bool is_all_or_none; \
+ bool is_simple; \
}) \
AST_KIND(UnionType, "union type", struct { \
Scope *scope; \
diff --git a/src/types.cpp b/src/types.cpp
index 911cd4448..a7f2bfda2 100644
--- a/src/types.cpp
+++ b/src/types.cpp
@@ -163,6 +163,7 @@ struct TypeStruct {
bool is_packed : 1;
bool is_raw_union : 1;
bool is_all_or_none : 1;
+ bool is_simple : 1;
bool is_poly_specialized : 1;
std::atomic<bool> are_offsets_being_processed;
@@ -2701,12 +2702,16 @@ gb_internal bool is_type_simple_compare(Type *t) {
case Type_SoaPointer:
case Type_Proc:
case Type_BitSet:
+ case Type_BitField:
return true;
case Type_Matrix:
return is_type_simple_compare(t->Matrix.elem);
case Type_Struct:
+ if (t->Struct.is_simple) {
+ return true;
+ }
for_array(i, t->Struct.fields) {
Entity *f = t->Struct.fields[i];
if (!is_type_simple_compare(f->type)) {
@@ -2728,6 +2733,16 @@ gb_internal bool is_type_simple_compare(Type *t) {
case Type_SimdVector:
return is_type_simple_compare(t->SimdVector.elem);
+ case Type_Tuple:
+ if (t->Tuple.variables.count == 1) {
+ return is_type_simple_compare(t->Tuple.variables[0]->type);
+ }
+ break;
+
+ case Type_Slice:
+ case Type_DynamicArray:
+ case Type_Map:
+ return false;
}
return false;
@@ -2757,12 +2772,16 @@ gb_internal bool is_type_nearly_simple_compare(Type *t) {
case Type_SoaPointer:
case Type_Proc:
case Type_BitSet:
+ case Type_BitField:
return true;
case Type_Matrix:
return is_type_nearly_simple_compare(t->Matrix.elem);
case Type_Struct:
+ if (t->Struct.is_simple) {
+ return true;
+ }
for_array(i, t->Struct.fields) {
Entity *f = t->Struct.fields[i];
if (!is_type_nearly_simple_compare(f->type)) {
@@ -2784,6 +2803,17 @@ gb_internal bool is_type_nearly_simple_compare(Type *t) {
case Type_SimdVector:
return is_type_nearly_simple_compare(t->SimdVector.elem);
+ case Type_Tuple:
+ if (t->Tuple.variables.count == 1) {
+ return is_type_nearly_simple_compare(t->Tuple.variables[0]->type);
+ }
+ break;
+
+ case Type_Slice:
+ case Type_DynamicArray:
+ case Type_Map:
+ return false;
+
}
return false;
@@ -5099,9 +5129,11 @@ gb_internal gbString write_type_to_string(gbString str, Type *type, bool shortha
str = gb_string_appendc(str, ")");
}
- if (type->Struct.is_packed) str = gb_string_appendc(str, " #packed");
- if (type->Struct.is_raw_union) str = gb_string_appendc(str, " #raw_union");
+ if (type->Struct.is_packed) str = gb_string_appendc(str, " #packed");
+ if (type->Struct.is_raw_union) str = gb_string_appendc(str, " #raw_union");
if (type->Struct.custom_align != 0) str = gb_string_append_fmt(str, " #align %d", cast(int)type->Struct.custom_align);
+ if (type->Struct.is_all_or_none) str = gb_string_appendc(str, " #all_or_none");
+ if (type->Struct.is_simple) str = gb_string_appendc(str, " #simple");
str = gb_string_appendc(str, " {");
diff --git a/tests/benchmark/crypto/benchmark_ecc.odin b/tests/benchmark/crypto/benchmark_ecc.odin
index 16ca798dc..52a1a4ac1 100644
--- a/tests/benchmark/crypto/benchmark_ecc.odin
+++ b/tests/benchmark/crypto/benchmark_ecc.odin
@@ -2,13 +2,14 @@ package benchmark_core_crypto
import "base:runtime"
import "core:encoding/hex"
+import "core:log"
import "core:testing"
import "core:text/table"
import "core:time"
+import "core:crypto"
+import "core:crypto/ecdh"
import "core:crypto/ed25519"
-import "core:crypto/x25519"
-import "core:crypto/x448"
@(private = "file")
ECDH_ITERS :: 10000
@@ -25,6 +26,10 @@ benchmark_crypto_ecc :: proc(t: ^testing.T) {
@(private = "file")
bench_ecdh :: proc() {
+ if !crypto.HAS_RAND_BYTES {
+ log.warnf("ECDH benchmarks skipped, no system entropy source")
+ }
+
tbl: table.Table
table.init(&tbl)
defer table.destroy(&tbl)
@@ -42,61 +47,35 @@ bench_ecdh :: proc() {
)
}
- scalar_bp, scalar := bench_x25519()
- append_tbl(&tbl, "X25519", scalar_bp, scalar)
-
- scalar_bp, scalar = bench_x448()
- append_tbl(&tbl, "X448", scalar_bp, scalar)
-
- log_table(&tbl)
-}
-
-@(private = "file")
-bench_x25519 :: proc() -> (bp, sc: time.Duration) {
- point_str := "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"
- scalar_str := "cafebabecafebabecafebabecafebabecafebabecafebabecafebabecafebabe"
-
- point, _ := hex.decode(transmute([]byte)(point_str), context.temp_allocator)
- scalar, _ := hex.decode(transmute([]byte)(scalar_str), context.temp_allocator)
- out: [x25519.POINT_SIZE]byte = ---
-
- start := time.tick_now()
- for _ in 0 ..< ECDH_ITERS {
- x25519.scalarmult_basepoint(out[:], scalar[:])
- }
- bp = time.tick_since(start) / ECDH_ITERS
-
- start = time.tick_now()
- for _ in 0 ..< ECDH_ITERS {
- x25519.scalarmult(out[:], scalar[:], point[:])
- }
- sc = time.tick_since(start) / ECDH_ITERS
-
- return
-}
-
-@(private = "file")
-bench_x448 :: proc() -> (bp, sc: time.Duration) {
- point_str := "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"
- scalar_str := "cafebabecafebabecafebabecafebabecafebabecafebabecafebabecafebabecafebabecafebabecafebabecafebabecafebabecafebabe"
-
- point, _ := hex.decode(transmute([]byte)(point_str), context.temp_allocator)
- scalar, _ := hex.decode(transmute([]byte)(scalar_str), context.temp_allocator)
- out: [x448.POINT_SIZE]byte = ---
-
- start := time.tick_now()
- for _ in 0 ..< ECDH_ITERS {
- x448.scalarmult_basepoint(out[:], scalar[:])
- }
- bp = time.tick_since(start) / ECDH_ITERS
-
- start = time.tick_now()
- for _ in 0 ..< ECDH_ITERS {
- x448.scalarmult(out[:], scalar[:], point[:])
+ for algo in ecdh.Curve {
+ if algo == .Invalid {
+ continue
+ }
+ algo_name := ecdh.CURVE_NAMES[algo]
+
+ priv_key_alice: ecdh.Private_Key
+ start := time.tick_now()
+ for _ in 0 ..< ECDH_ITERS {
+ _ = ecdh.private_key_generate(&priv_key_alice, algo)
+ }
+ bp := time.tick_since(start) / ECDH_ITERS
+
+ pub_key_alice: ecdh.Public_Key
+ ecdh.public_key_set_priv(&pub_key_alice, &priv_key_alice)
+
+ priv_key_bob: ecdh.Private_Key
+ _ = ecdh.private_key_generate(&priv_key_bob, algo)
+ ss := make([]byte, ecdh.SHARED_SECRET_SIZES[algo], context.temp_allocator)
+ start = time.tick_now()
+ for _ in 0 ..< ECDH_ITERS {
+ _ = ecdh.ecdh(&priv_key_bob, &pub_key_alice, ss)
+ }
+ sc := time.tick_since(start) / ECDH_ITERS
+
+ append_tbl(&tbl, algo_name, bp, sc)
}
- sc = time.tick_since(start) / ECDH_ITERS
- return
+ log_table(&tbl)
}
@(private = "file")
diff --git a/tests/core/crypto/test_core_crypto_ecdh.odin b/tests/core/crypto/test_core_crypto_ecdh.odin
new file mode 100644
index 000000000..87c9e8a4d
--- /dev/null
+++ b/tests/core/crypto/test_core_crypto_ecdh.odin
@@ -0,0 +1,154 @@
+package test_core_crypto
+
+import "core:encoding/hex"
+import "core:testing"
+
+import "core:crypto/ecdh"
+
+@(test)
+test_ecdh :: proc(t: ^testing.T) {
+ test_vectors := []struct {
+ curve: ecdh.Curve,
+ scalar: string,
+ point: string,
+ product: string,
+ } {
+ // X25519 Test vectors from RFC 7748
+ {
+ .X25519,
+ "a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4",
+ "e6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c",
+ "c3da55379de9c6908e94ea4df28d084f32eccf03491c71f754b4075577a28552",
+ },
+ {
+ .X25519,
+ "4b66e9d4d1b4673c5ad22691957d6af5c11b6421e0ea01d42ca4169e7918ba0d",
+ "e5210f12786811d3f4b7959d0538ae2c31dbe7106fc03c3efc4cd549c715a493",
+ "95cbde9476e8907d7aade45cb4b873f88b595a68799fa152e6f8f7647aac7957",
+ },
+ // X448 Test vectors from RFC 7748
+ {
+ .X448,
+ "3d262fddf9ec8e88495266fea19a34d28882acef045104d0d1aae121700a779c984c24f8cdd78fbff44943eba368f54b29259a4f1c600ad3",
+ "06fce640fa3487bfda5f6cf2d5263f8aad88334cbd07437f020f08f9814dc031ddbdc38c19c6da2583fa5429db94ada18aa7a7fb4ef8a086",
+ "ce3e4ff95a60dc6697da1db1d85e6afbdf79b50a2412d7546d5f239fe14fbaadeb445fc66a01b0779d98223961111e21766282f73dd96b6f",
+ },
+ {
+ .X448,
+ "203d494428b8399352665ddca42f9de8fef600908e0d461cb021f8c538345dd77c3e4806e25f46d3315c44e0a5b4371282dd2c8d5be3095f",
+ "0fbcc2f993cd56d3305b0b7d9e55d4c1a8fb5dbb52f8e9a1e9b6201b165d015894e56c4d3570bee52fe205e28a78b91cdfbde71ce8d157db",
+ "884a02576239ff7a2f2f63b2db6a9ff37047ac13568e1e30fe63c4a7ad1b3ee3a5700df34321d62077e63633c575c1c954514e99da7c179d",
+ },
+ // secp256r1 Test vectors (subset) from NIST CAVP
+ {
+ .SECP256R1,
+ "7d7dc5f71eb29ddaf80d6214632eeae03d9058af1fb6d22ed80badb62bc1a534",
+ "04700c48f77f56584c5cc632ca65640db91b6bacce3a4df6b42ce7cc838833d287db71e509e3fd9b060ddb20ba5c51dcc5948d46fbf640dfe0441782cab85fa4ac",
+ "46fc62106420ff012e54a434fbdd2d25ccc5852060561e68040dd7778997bd7b",
+ },
+ {
+ .SECP256R1,
+ "38f65d6dce47676044d58ce5139582d568f64bb16098d179dbab07741dd5caf5",
+ "04809f04289c64348c01515eb03d5ce7ac1a8cb9498f5caa50197e58d43a86a7aeb29d84e811197f25eba8f5194092cb6ff440e26d4421011372461f579271cda3",
+ "057d636096cb80b67a8c038c890e887d1adfa4195e9b3ce241c8a778c59cda67",
+ },
+ }
+
+ for v, _ in test_vectors {
+ raw_scalar, _ := hex.decode(transmute([]byte)(v.scalar), context.temp_allocator)
+ raw_point, _ := hex.decode(transmute([]byte)(v.point), context.temp_allocator)
+
+ pub_key: ecdh.Public_Key
+ priv_key: ecdh.Private_Key
+
+ ok := ecdh.private_key_set_bytes(&priv_key, v.curve, raw_scalar)
+ testing.expectf(t, ok, "failed to deserialize private key: %v %x", v.curve, raw_scalar)
+
+ ok = ecdh.public_key_set_bytes(&pub_key, v.curve, raw_point)
+ testing.expectf(t, ok, "failed to deserialize public key: %v %x", v.curve, raw_scalar)
+
+ shared_secret := make([]byte, ecdh.shared_secret_size(&pub_key), context.temp_allocator)
+ ok = ecdh.ecdh(&priv_key, &pub_key, shared_secret)
+ testing.expectf(t, ok, "ecdh failed: %v %v %v", v.curve, &priv_key, &pub_key)
+
+ ss_str := string(hex.encode(shared_secret, context.temp_allocator))
+ testing.expectf(
+ t,
+ ss_str == v.product,
+ "Expected %s for %v %s * %s, but got %s instead",
+ v.product,
+ v.curve,
+ v.scalar,
+ v.point,
+ ss_str,
+ )
+ }
+}
+
+@(test)
+test_ecdh_scalar_basemult :: proc(t: ^testing.T) {
+ test_vectors := []struct {
+ curve: ecdh.Curve,
+ scalar : string,
+ point: string,
+ } {
+ // X25519 from RFC 7748 6.1
+ {
+ .X25519,
+ "77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a",
+ "8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a",
+ },
+ {
+ .X25519,
+ "5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb",
+ "de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f",
+ },
+ // X448 from RFC 7748 6.2
+ {
+ .X448,
+ "9a8f4925d1519f5775cf46b04b5800d4ee9ee8bae8bc5565d498c28dd9c9baf574a9419744897391006382a6f127ab1d9ac2d8c0a598726b",
+ "9b08f7cc31b7e3e67d22d5aea121074a273bd2b83de09c63faa73d2c22c5d9bbc836647241d953d40c5b12da88120d53177f80e532c41fa0",
+ },
+ {
+ .X448,
+ "1c306a7ac2a0e2e0990b294470cba339e6453772b075811d8fad0d1d6927c120bb5ee8972b0d3e21374c9c921b09d1b0366f10b65173992d",
+ "3eb7a829b0cd20f5bcfc0b599b6feccf6da4627107bdb0d4f345b43027d8b972fc3e34fb4232a13ca706dcb57aec3dae07bdc1c67bf33609",
+ },
+ // secp256r1 Test vectors (subset) from NIST CAVP
+ {
+ .SECP256R1,
+ "7d7dc5f71eb29ddaf80d6214632eeae03d9058af1fb6d22ed80badb62bc1a534",
+ "04ead218590119e8876b29146ff89ca61770c4edbbf97d38ce385ed281d8a6b23028af61281fd35e2fa7002523acc85a429cb06ee6648325389f59edfce1405141",
+ },
+ {
+ .SECP256R1,
+ "38f65d6dce47676044d58ce5139582d568f64bb16098d179dbab07741dd5caf5",
+ "04119f2f047902782ab0c9e27a54aff5eb9b964829ca99c06b02ddba95b0a3f6d08f52b726664cac366fc98ac7a012b2682cbd962e5acb544671d41b9445704d1d",
+ },
+ }
+
+ for v, _ in test_vectors {
+ raw_scalar, _ := hex.decode(transmute([]byte)(v.scalar), context.temp_allocator)
+
+ priv_key: ecdh.Private_Key
+ pub_key: ecdh.Public_Key
+
+ ok := ecdh.private_key_set_bytes(&priv_key, v.curve, raw_scalar)
+ testing.expectf(t, ok, "failed to deserialize private key: %v %x", v.curve, raw_scalar)
+
+ ecdh.public_key_set_priv(&pub_key, &priv_key)
+ b := make([]byte, ecdh.key_size(&pub_key), context.temp_allocator)
+ ecdh.public_key_bytes(&pub_key, b)
+
+ pub_str := string(hex.encode(b, context.temp_allocator))
+ testing.expectf(
+ t,
+ pub_str == v.point,
+ "Expected %s for %v %s * G, but got %s instead",
+ v.point,
+ v.curve,
+ v.scalar,
+ pub_str,
+ )
+ }
+} \ No newline at end of file
diff --git a/tests/core/crypto/test_core_crypto_edwards.odin b/tests/core/crypto/test_core_crypto_edwards.odin
index 61933c00f..2da98000c 100644
--- a/tests/core/crypto/test_core_crypto_edwards.odin
+++ b/tests/core/crypto/test_core_crypto_edwards.odin
@@ -6,11 +6,9 @@ import "core:testing"
import field "core:crypto/_fiat/field_curve25519"
import "core:crypto/ed25519"
import "core:crypto/ristretto255"
-import "core:crypto/x25519"
-import "core:crypto/x448"
@(test)
-test_sqrt_ratio_m1 :: proc(t: ^testing.T) {
+test_edwards25519_sqrt_ratio_m1 :: proc(t: ^testing.T) {
test_vectors := []struct {
u: string,
v: string,
@@ -625,136 +623,14 @@ test_ed25519 :: proc(t: ^testing.T) {
}
}
-@(test)
-test_x25519 :: proc(t: ^testing.T) {
- // Local copy of this so that the base point doesn't need to be exported.
- _BASE_POINT: [32]byte = {
- 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- }
-
- test_vectors := []struct {
- scalar: string,
- point: string,
- product: string,
- } {
- // Test vectors from RFC 7748
- {
- "a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4",
- "e6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c",
- "c3da55379de9c6908e94ea4df28d084f32eccf03491c71f754b4075577a28552",
- },
- {
- "4b66e9d4d1b4673c5ad22691957d6af5c11b6421e0ea01d42ca4169e7918ba0d",
- "e5210f12786811d3f4b7959d0538ae2c31dbe7106fc03c3efc4cd549c715a493",
- "95cbde9476e8907d7aade45cb4b873f88b595a68799fa152e6f8f7647aac7957",
- },
- }
- for v, _ in test_vectors {
- scalar, _ := hex.decode(transmute([]byte)(v.scalar), context.temp_allocator)
- point, _ := hex.decode(transmute([]byte)(v.point), context.temp_allocator)
-
- derived_point: [x25519.POINT_SIZE]byte
- x25519.scalarmult(derived_point[:], scalar[:], point[:])
- derived_point_str := string(hex.encode(derived_point[:], context.temp_allocator))
-
- testing.expectf(
- t,
- derived_point_str == v.product,
- "Expected %s for %s * %s, but got %s instead",
- v.product,
- v.scalar,
- v.point,
- derived_point_str,
- )
-
- // Abuse the test vectors to sanity-check the scalar-basepoint multiply.
- p1, p2: [x25519.POINT_SIZE]byte
- x25519.scalarmult_basepoint(p1[:], scalar[:])
- x25519.scalarmult(p2[:], scalar[:], _BASE_POINT[:])
- p1_str := string(hex.encode(p1[:], context.temp_allocator))
- p2_str := string(hex.encode(p2[:], context.temp_allocator))
- testing.expectf(
- t,
- p1_str == p2_str,
- "Expected %s for %s * basepoint, but got %s instead",
- p2_str,
- v.scalar,
- p1_str,
- )
- }
-}
-
-@(test)
-test_x448 :: proc(t: ^testing.T) {
- // Local copy of this so that the base point doesn't need to be exported.
- _BASE_POINT: [56]byte = {
- 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- }
-
- test_vectors := []struct {
- scalar: string,
- point: string,
- product: string,
- } {
- // Test vectors from RFC 7748
- {
- "3d262fddf9ec8e88495266fea19a34d28882acef045104d0d1aae121700a779c984c24f8cdd78fbff44943eba368f54b29259a4f1c600ad3",
- "06fce640fa3487bfda5f6cf2d5263f8aad88334cbd07437f020f08f9814dc031ddbdc38c19c6da2583fa5429db94ada18aa7a7fb4ef8a086",
- "ce3e4ff95a60dc6697da1db1d85e6afbdf79b50a2412d7546d5f239fe14fbaadeb445fc66a01b0779d98223961111e21766282f73dd96b6f",
- },
- {
- "203d494428b8399352665ddca42f9de8fef600908e0d461cb021f8c538345dd77c3e4806e25f46d3315c44e0a5b4371282dd2c8d5be3095f",
- "0fbcc2f993cd56d3305b0b7d9e55d4c1a8fb5dbb52f8e9a1e9b6201b165d015894e56c4d3570bee52fe205e28a78b91cdfbde71ce8d157db",
- "884a02576239ff7a2f2f63b2db6a9ff37047ac13568e1e30fe63c4a7ad1b3ee3a5700df34321d62077e63633c575c1c954514e99da7c179d",
- },
- }
- for v, _ in test_vectors {
- scalar, _ := hex.decode(transmute([]byte)(v.scalar), context.temp_allocator)
- point, _ := hex.decode(transmute([]byte)(v.point), context.temp_allocator)
-
- derived_point: [x448.POINT_SIZE]byte
- x448.scalarmult(derived_point[:], scalar[:], point[:])
- derived_point_str := string(hex.encode(derived_point[:], context.temp_allocator))
-
- testing.expectf(
- t,
- derived_point_str == v.product,
- "Expected %s for %s * %s, but got %s instead",
- v.product,
- v.scalar,
- v.point,
- derived_point_str,
- )
-
- // Abuse the test vectors to sanity-check the scalar-basepoint multiply.
- p1, p2: [x448.POINT_SIZE]byte
- x448.scalarmult_basepoint(p1[:], scalar[:])
- x448.scalarmult(p2[:], scalar[:], _BASE_POINT[:])
- p1_str := string(hex.encode(p1[:], context.temp_allocator))
- p2_str := string(hex.encode(p2[:], context.temp_allocator))
- testing.expectf(
- t,
- p1_str == p2_str,
- "Expected %s for %s * basepoint, but got %s instead",
- p2_str,
- v.scalar,
- p1_str,
- )
- }
-}
-
-@(private)
+@(private="file")
ge_str :: proc(ge: ^ristretto255.Group_Element) -> string {
b: [ristretto255.ELEMENT_SIZE]byte
ristretto255.ge_bytes(ge, b[:])
return string(hex.encode(b[:], context.temp_allocator))
}
-@(private)
+@(private="file")
fe_str :: proc(fe: ^field.Tight_Field_Element) -> string {
b: [32]byte
field.fe_to_bytes(&b, fe)
diff --git a/tests/core/crypto/test_core_crypto_weierstrass.odin b/tests/core/crypto/test_core_crypto_weierstrass.odin
new file mode 100644
index 000000000..206e98bd7
--- /dev/null
+++ b/tests/core/crypto/test_core_crypto_weierstrass.odin
@@ -0,0 +1,486 @@
+package test_core_crypto
+
+import ec "core:crypto/_weierstrass"
+import "core:encoding/hex"
+import "core:math/big"
+import "core:testing"
+
+@(private="file")
+P256_G_X :: "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296"
+@(private="file")
+P256_G_Y :: "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5"
+
+@(private="file")
+P256_G_UNCOMPRESSED :: "04" + P256_G_X + P256_G_Y
+
+@(test)
+test_p256_a :: proc(t: ^testing.T) {
+ a_str := "ffffffff00000001000000000000000000000000fffffffffffffffffffffffc"
+
+ fe, a_fe: ec.Field_Element_p256r1
+ ec.fe_a(&fe)
+ ec.fe_a(&a_fe)
+
+ b: [32]byte
+ ec.fe_bytes(b[:], &fe)
+
+ s := (string)(hex.encode(b[:], context.temp_allocator))
+
+ testing.expect(t, s == a_str)
+
+ ec.fe_zero(&fe)
+ ec.fe_set_bytes(&fe, b[:])
+
+ testing.expect(t, ec.fe_equal(&fe, &a_fe) == 1)
+}
+
+@(test)
+test_p256_b :: proc(t: ^testing.T) {
+ b_str := "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b"
+
+ fe, b_fe: ec.Field_Element_p256r1
+ ec.fe_b(&fe)
+ ec.fe_b(&b_fe)
+
+ b: [32]byte
+ ec.fe_bytes(b[:], &fe)
+
+ s := (string)(hex.encode(b[:], context.temp_allocator))
+
+ testing.expect(t, s == b_str)
+
+ ec.fe_zero(&fe)
+ ec.fe_set_bytes(&fe, b[:])
+
+ testing.expect(t, ec.fe_equal(&fe, &b_fe) == 1)
+}
+
+@(test)
+test_p256_g_x :: proc(t: ^testing.T) {
+ fe, x_fe: ec.Field_Element_p256r1
+ ec.fe_gen_x(&fe)
+ ec.fe_gen_x(&x_fe)
+
+ b: [32]byte
+ ec.fe_bytes(b[:], &fe)
+
+ s := (string)(hex.encode(b[:], context.temp_allocator))
+ testing.expect(t, s == P256_G_X)
+
+ ec.fe_zero(&fe)
+ ec.fe_set_bytes(&fe, b[:])
+
+ testing.expect(t, ec.fe_equal(&fe, &x_fe) == 1)
+}
+
+@(test)
+test_p256_g_y :: proc(t: ^testing.T) {
+ fe, y_fe: ec.Field_Element_p256r1
+ ec.fe_gen_y(&fe)
+ ec.fe_gen_y(&y_fe)
+
+ b: [32]byte
+ ec.fe_bytes(b[:], &fe)
+
+ s := (string)(hex.encode(b[:], context.temp_allocator))
+ testing.expect(t, s == P256_G_Y)
+
+ ec.fe_zero(&fe)
+ ec.fe_set_bytes(&fe, b[:])
+
+ testing.expect(t, ec.fe_equal(&fe, &y_fe) == 1)
+}
+
+@(test)
+test_p256_scalar_reduce :: proc(t: ^testing.T) {
+ test_vectors := []struct {
+ raw: string,
+ reduced: string,
+ } {
+ // n
+ {
+ "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ },
+ // n + 1
+ {
+ "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552",
+ "0000000000000000000000000000000000000000000000000000000000000001",
+ },
+ // 2^384 (Sage)
+ {
+ "01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "431905529c0166ce652e96b7ccca0a99679b73e19ad16947f01cf013fc632551",
+ },
+ // SHA384 odin-linux-amd64-dev-2026-01.tar.gz (Sage)
+ {
+ "87622f79b4b0e76001f9c99b0337b61a0bcd2b5a8e9a3937176825ad75ef0fe8742a348a251dd2682d711f76b33df3e6",
+ "f66db86e28d903033d1e17d818c0eb13fe3d1ae095b4d2ecbcd1a1eccf9f2f8c",
+ },
+ // SHA512 odin-linux-amd64-dev-2026-01.tar.gz (Sage)
+ {
+ "6f85507cec3a35fdb3d4f40d23583681144561e77bc4ea88ab0ea219d5c17b7c9178f5f5a6296a2d18eddd4bdf19e61830fc85d7de23fd4fbde31c4cf6694719",
+ "3217ecbee32c8b0dfcca0f10a884fe43658fbe91458f25d0f1bf2075759c5ebe",
+ },
+ }
+
+ for v, _ in test_vectors {
+ raw_bytes, _ := hex.decode(transmute([]byte)(v.raw), context.temp_allocator)
+
+ sc: ec.Scalar_p256r1
+ _ = ec.sc_set_bytes(&sc, raw_bytes)
+
+ b: [ec.SC_SIZE_P256R1]byte
+ ec.sc_bytes(b[:], &sc)
+ s := (string)(hex.encode(b[:], context.temp_allocator))
+
+ testing.expectf(t, v.reduced == s, "sc: raw %s reduced: %s, expected: %s", v.raw, s, v.reduced)
+ }
+}
+
+@(test)
+test_p256_scalar_mul :: proc(t: ^testing.T) {
+ test_vectors := []struct {
+ scalar: string, // NOTE: Base 10
+ x, y: string,
+ } {
+ // Test vectors from http://point-at-infinity.org/ecc/nisttv
+ {
+ "1",
+ "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
+ "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
+
+ },
+ {
+ "2",
+ "7CF27B188D034F7E8A52380304B51AC3C08969E277F21B35A60B48FC47669978",
+ "07775510DB8ED040293D9AC69F7430DBBA7DADE63CE982299E04B79D227873D1",
+ },
+ {
+ "3",
+ "5ECBE4D1A6330A44C8F7EF951D4BF165E6C6B721EFADA985FB41661BC6E7FD6C",
+ "8734640C4998FF7E374B06CE1A64A2ECD82AB036384FB83D9A79B127A27D5032",
+ },
+ {
+ "4",
+ "E2534A3532D08FBBA02DDE659EE62BD0031FE2DB785596EF509302446B030852",
+ "E0F1575A4C633CC719DFEE5FDA862D764EFC96C3F30EE0055C42C23F184ED8C6",
+ },
+ {
+ "5",
+ "51590B7A515140D2D784C85608668FDFEF8C82FD1F5BE52421554A0DC3D033ED",
+ "E0C17DA8904A727D8AE1BF36BF8A79260D012F00D4D80888D1D0BB44FDA16DA4",
+ },
+ {
+ "6",
+ "B01A172A76A4602C92D3242CB897DDE3024C740DEBB215B4C6B0AAE93C2291A9",
+ "E85C10743237DAD56FEC0E2DFBA703791C00F7701C7E16BDFD7C48538FC77FE2",
+ },
+ {
+ "7",
+ "8E533B6FA0BF7B4625BB30667C01FB607EF9F8B8A80FEF5B300628703187B2A3",
+ "73EB1DBDE03318366D069F83A6F5900053C73633CB041B21C55E1A86C1F400B4",
+ },
+ {
+ "8",
+ "62D9779DBEE9B0534042742D3AB54CADC1D238980FCE97DBB4DD9DC1DB6FB393",
+ "AD5ACCBD91E9D8244FF15D771167CEE0A2ED51F6BBE76A78DA540A6A0F09957E",
+ },
+ {
+ "9",
+ "EA68D7B6FEDF0B71878938D51D71F8729E0ACB8C2C6DF8B3D79E8A4B90949EE0",
+ "2A2744C972C9FCE787014A964A8EA0C84D714FEAA4DE823FE85A224A4DD048FA",
+ },
+ {
+ "10",
+ "CEF66D6B2A3A993E591214D1EA223FB545CA6C471C48306E4C36069404C5723F",
+ "878662A229AAAE906E123CDD9D3B4C10590DED29FE751EEECA34BBAA44AF0773",
+ },
+ {
+ "11",
+ "3ED113B7883B4C590638379DB0C21CDA16742ED0255048BF433391D374BC21D1",
+ "9099209ACCC4C8A224C843AFA4F4C68A090D04DA5E9889DAE2F8EEFCE82A3740",
+ },
+ {
+ "12",
+ "741DD5BDA817D95E4626537320E5D55179983028B2F82C99D500C5EE8624E3C4",
+ "0770B46A9C385FDC567383554887B1548EEB912C35BA5CA71995FF22CD4481D3",
+ },
+ {
+ "13",
+ "177C837AE0AC495A61805DF2D85EE2FC792E284B65EAD58A98E15D9D46072C01",
+ "63BB58CD4EBEA558A24091ADB40F4E7226EE14C3A1FB4DF39C43BBE2EFC7BFD8",
+ },
+ {
+ "14",
+ "54E77A001C3862B97A76647F4336DF3CF126ACBE7A069C5E5709277324D2920B",
+ "F599F1BB29F4317542121F8C05A2E7C37171EA77735090081BA7C82F60D0B375",
+ },
+ {
+ "15",
+ "F0454DC6971ABAE7ADFB378999888265AE03AF92DE3A0EF163668C63E59B9D5F",
+ "B5B93EE3592E2D1F4E6594E51F9643E62A3B21CE75B5FA3F47E59CDE0D034F36",
+ },
+ {
+ "16",
+ "76A94D138A6B41858B821C629836315FCD28392EFF6CA038A5EB4787E1277C6E",
+ "A985FE61341F260E6CB0A1B5E11E87208599A0040FC78BAA0E9DDD724B8C5110",
+ },
+ {
+ "17",
+ "47776904C0F1CC3A9C0984B66F75301A5FA68678F0D64AF8BA1ABCE34738A73E",
+ "AA005EE6B5B957286231856577648E8381B2804428D5733F32F787FF71F1FCDC",
+ },
+ {
+ "18",
+ "1057E0AB5780F470DEFC9378D1C7C87437BB4C6F9EA55C63D936266DBD781FDA",
+ "F6F1645A15CBE5DC9FA9B7DFD96EE5A7DCC11B5C5EF4F1F78D83B3393C6A45A2",
+ },
+ {
+ "19",
+ "CB6D2861102C0C25CE39B7C17108C507782C452257884895C1FC7B74AB03ED83",
+ "58D7614B24D9EF515C35E7100D6D6CE4A496716E30FA3E03E39150752BCECDAA",
+ },
+ {
+ "20",
+ "83A01A9378395BAB9BCD6A0AD03CC56D56E6B19250465A94A234DC4C6B28DA9A",
+ "76E49B6DE2F73234AE6A5EB9D612B75C9F2202BB6923F54FF8240AAA86F640B8",
+ },
+ {
+ "112233445566778899",
+ "339150844EC15234807FE862A86BE77977DBFB3AE3D96F4C22795513AEAAB82F",
+ "B1C14DDFDC8EC1B2583F51E85A5EB3A155840F2034730E9B5ADA38B674336A21",
+ },
+ {
+ "112233445566778899112233445566778899",
+ "1B7E046A076CC25E6D7FA5003F6729F665CC3241B5ADAB12B498CD32F2803264",
+ "BFEA79BE2B666B073DB69A2A241ADAB0738FE9D2DD28B5604EB8C8CF097C457B",
+ },
+ {
+ "029852220098221261079183923314599206100666902414330245206392788703677545185283",
+ "9EACE8F4B071E677C5350B02F2BB2B384AAE89D58AA72CA97A170572E0FB222F",
+ "1BBDAEC2430B09B93F7CB08678636CE12EAAFD58390699B5FD2F6E1188FC2A78",
+ },
+ {
+ "057896042899961394862005778464643882389978449576758748073725983489954366354431",
+ "878F22CC6DB6048D2B767268F22FFAD8E56AB8E2DC615F7BD89F1E350500DD8D",
+ "714A5D7BB901C9C5853400D12341A892EF45D87FC553786756C4F0C9391D763E",
+ },
+ {
+ "57896042899961394862005778464643882389978449576758748073725983489954366354431",
+ "878F22CC6DB6048D2B767268F22FFAD8E56AB8E2DC615F7BD89F1E350500DD8D",
+ "714A5D7BB901C9C5853400D12341A892EF45D87FC553786756C4F0C9391D763E",
+ },
+ {
+ "1766845392945710151501889105729049882997660004824848915955419660366636031",
+ "659A379625AB122F2512B8DADA02C6348D53B54452DFF67AC7ACE4E8856295CA",
+ "49D81AB97B648464D0B4A288BD7818FAB41A16426E943527C4FED8736C53D0F6",
+ },
+ {
+ "28948025760307534517734791687894775804466072615242963443097661355606862201087",
+ "CBCEAAA8A4DD44BBCE58E8DB7740A5510EC2CB7EA8DA8D8F036B3FB04CDA4DE4",
+ "4BD7AA301A80D7F59FD983FEDBE59BB7B2863FE46494935E3745B360E32332FA",
+ },
+ {
+ "113078210460870548944811695960290644973229224625838436424477095834645696384",
+ "F0C4A0576154FF3A33A3460D42EAED806E854DFA37125221D37935124BA462A4",
+ "5B392FA964434D29EEC6C9DBC261CF116796864AA2FAADB984A2DF38D1AEF7A3",
+ },
+ {
+ "12078056106883488161242983286051341125085761470677906721917479268909056",
+ "5E6C8524B6369530B12C62D31EC53E0288173BD662BDF680B53A41ECBCAD00CC",
+ "447FE742C2BFEF4D0DB14B5B83A2682309B5618E0064A94804E9282179FE089F",
+ },
+ {
+ "57782969857385448082319957860328652998540760998293976083718804450708503920639",
+ "03792E541BC209076A3D7920A915021ECD396A6EB5C3960024BE5575F3223484",
+ "FC774AE092403101563B712F68170312304F20C80B40C06282063DB25F268DE4",
+ },
+ {
+ "57896017119460046759583662757090100341435943767777707906455551163257755533312",
+ "2379FF85AB693CDF901D6CE6F2473F39C04A2FE3DCD842CE7AAB0E002095BCF8",
+ "F8B476530A634589D5129E46F322B02FBC610A703D80875EE70D7CE1877436A1",
+ },
+ {
+ "452312848374287284681282171017647412726433684238464212999305864837160993279",
+ "C1E4072C529BF2F44DA769EFC934472848003B3AF2C0F5AA8F8DDBD53E12ED7C",
+ "39A6EE77812BB37E8079CD01ED649D3830FCA46F718C1D3993E4A591824ABCDB",
+ },
+ {
+ "904571339174065134293634407946054000774746055866917729876676367558469746684",
+ "34DFBC09404C21E250A9B40FA8772897AC63A094877DB65862B61BD1507B34F3",
+ "CF6F8A876C6F99CEAEC87148F18C7E1E0DA6E165FFC8ED82ABB65955215F77D3",
+ },
+ {
+ "115792089210356248762697446949407573529996955224135760342422259061068512044349",
+ "83A01A9378395BAB9BCD6A0AD03CC56D56E6B19250465A94A234DC4C6B28DA9A",
+ "891B64911D08CDCC5195A14629ED48A360DDFD4596DC0AB007DBF5557909BF47",
+ },
+ {
+ "115792089210356248762697446949407573529996955224135760342422259061068512044350",
+ "CB6D2861102C0C25CE39B7C17108C507782C452257884895C1FC7B74AB03ED83",
+ "A7289EB3DB2610AFA3CA18EFF292931B5B698E92CF05C1FC1C6EAF8AD4313255",
+ },
+ {
+ "115792089210356248762697446949407573529996955224135760342422259061068512044351",
+ "1057E0AB5780F470DEFC9378D1C7C87437BB4C6F9EA55C63D936266DBD781FDA",
+ "090E9BA4EA341A246056482026911A58233EE4A4A10B0E08727C4CC6C395BA5D",
+ },
+ {
+ "115792089210356248762697446949407573529996955224135760342422259061068512044352",
+ "47776904C0F1CC3A9C0984B66F75301A5FA68678F0D64AF8BA1ABCE34738A73E",
+ "55FFA1184A46A8D89DCE7A9A889B717C7E4D7FBCD72A8CC0CD0878008E0E0323",
+ },
+ {
+ "115792089210356248762697446949407573529996955224135760342422259061068512044353",
+ "76A94D138A6B41858B821C629836315FCD28392EFF6CA038A5EB4787E1277C6E",
+ "567A019DCBE0D9F2934F5E4A1EE178DF7A665FFCF0387455F162228DB473AEEF",
+ },
+ {
+ "115792089210356248762697446949407573529996955224135760342422259061068512044354",
+ "F0454DC6971ABAE7ADFB378999888265AE03AF92DE3A0EF163668C63E59B9D5F",
+ "4A46C11BA6D1D2E1B19A6B1AE069BC19D5C4DE328A4A05C0B81A6321F2FCB0C9",
+ },
+ {
+ "115792089210356248762697446949407573529996955224135760342422259061068512044355",
+ "54E77A001C3862B97A76647F4336DF3CF126ACBE7A069C5E5709277324D2920B",
+ "0A660E43D60BCE8BBDEDE073FA5D183C8E8E15898CAF6FF7E45837D09F2F4C8A",
+ },
+ {
+ "115792089210356248762697446949407573529996955224135760342422259061068512044356",
+ "177C837AE0AC495A61805DF2D85EE2FC792E284B65EAD58A98E15D9D46072C01",
+ "9C44A731B1415AA85DBF6E524BF0B18DD911EB3D5E04B20C63BC441D10384027",
+ },
+ {
+ "115792089210356248762697446949407573529996955224135760342422259061068512044357",
+ "741DD5BDA817D95E4626537320E5D55179983028B2F82C99D500C5EE8624E3C4",
+ "F88F4B9463C7A024A98C7CAAB7784EAB71146ED4CA45A358E66A00DD32BB7E2C",
+ },
+ {
+ "115792089210356248762697446949407573529996955224135760342422259061068512044358",
+ "3ED113B7883B4C590638379DB0C21CDA16742ED0255048BF433391D374BC21D1",
+ "6F66DF64333B375EDB37BC505B0B3975F6F2FB26A16776251D07110317D5C8BF",
+ },
+ {
+ "115792089210356248762697446949407573529996955224135760342422259061068512044359",
+ "CEF66D6B2A3A993E591214D1EA223FB545CA6C471C48306E4C36069404C5723F",
+ "78799D5CD655517091EDC32262C4B3EFA6F212D7018AE11135CB4455BB50F88C",
+ },
+ {
+ "115792089210356248762697446949407573529996955224135760342422259061068512044360",
+ "EA68D7B6FEDF0B71878938D51D71F8729E0ACB8C2C6DF8B3D79E8A4B90949EE0",
+ "D5D8BB358D36031978FEB569B5715F37B28EB0165B217DC017A5DDB5B22FB705",
+ },
+ {
+ "115792089210356248762697446949407573529996955224135760342422259061068512044361",
+ "62D9779DBEE9B0534042742D3AB54CADC1D238980FCE97DBB4DD9DC1DB6FB393",
+ "52A533416E1627DCB00EA288EE98311F5D12AE0A4418958725ABF595F0F66A81",
+ },
+ {
+ "115792089210356248762697446949407573529996955224135760342422259061068512044362",
+ "8E533B6FA0BF7B4625BB30667C01FB607EF9F8B8A80FEF5B300628703187B2A3",
+ "8C14E2411FCCE7CA92F9607C590A6FFFAC38C9CD34FBE4DE3AA1E5793E0BFF4B",
+ },
+ {
+ "115792089210356248762697446949407573529996955224135760342422259061068512044363",
+ "B01A172A76A4602C92D3242CB897DDE3024C740DEBB215B4C6B0AAE93C2291A9",
+ "17A3EF8ACDC8252B9013F1D20458FC86E3FF0890E381E9420283B7AC7038801D",
+ },
+ {
+ "115792089210356248762697446949407573529996955224135760342422259061068512044364",
+ "51590B7A515140D2D784C85608668FDFEF8C82FD1F5BE52421554A0DC3D033ED",
+ "1F3E82566FB58D83751E40C9407586D9F2FED1002B27F7772E2F44BB025E925B",
+ },
+ {
+ "115792089210356248762697446949407573529996955224135760342422259061068512044365",
+ "E2534A3532D08FBBA02DDE659EE62BD0031FE2DB785596EF509302446B030852",
+ "1F0EA8A4B39CC339E62011A02579D289B103693D0CF11FFAA3BD3DC0E7B12739",
+ },
+ {
+ "115792089210356248762697446949407573529996955224135760342422259061068512044366",
+ "5ECBE4D1A6330A44C8F7EF951D4BF165E6C6B721EFADA985FB41661BC6E7FD6C",
+ "78CB9BF2B6670082C8B4F931E59B5D1327D54FCAC7B047C265864ED85D82AFCD",
+ },
+ {
+ "115792089210356248762697446949407573529996955224135760342422259061068512044367",
+ "7CF27B188D034F7E8A52380304B51AC3C08969E277F21B35A60B48FC47669978",
+ "F888AAEE24712FC0D6C26539608BCF244582521AC3167DD661FB4862DD878C2E",
+ },
+ {
+ "115792089210356248762697446949407573529996955224135760342422259061068512044368",
+ "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
+ "B01CBD1C01E58065711814B583F061E9D431CCA994CEA1313449BF97C840AE0A",
+ },
+ }
+
+ for v, _ in test_vectors {
+ x_bytes, _ := hex.decode(transmute([]byte)(v.x), context.temp_allocator)
+ y_bytes, _ := hex.decode(transmute([]byte)(v.y), context.temp_allocator)
+
+ k_big: big.Int
+ err := big.set(&k_big, v.scalar, 10, context.temp_allocator)
+ testing.expectf(t, err == nil, "failed to parse k", err)
+
+ k_sz: int
+ k_sz, err = big.int_to_bytes_size(&k_big, allocator = context.temp_allocator)
+ testing.expect(t, err == nil)
+
+ k_bytes := make([]byte, k_sz, context.temp_allocator)
+ err = big.int_to_bytes_big(&k_big, k_bytes, allocator = context.temp_allocator)
+
+ p, q, expected, g: ec.Point_p256r1
+ sc: ec.Scalar_p256r1
+
+ _ = ec.sc_set_bytes(&sc, k_bytes)
+
+ ec.pt_generator(&g)
+ ok := ec.pt_set_xy_bytes(&expected, x_bytes, y_bytes)
+ testing.expectf(t, ok, "failed to set point; %s, %s", v.x, v.y)
+
+ ec.pt_scalar_mul(&p, &g, &sc)
+ ec.pt_scalar_mul_generator(&q, &sc)
+ ec.pt_rescale(&p, &p)
+ ec.pt_rescale(&q, &q)
+
+ testing.expect(t, ec.pt_equal(&p, &q) == 1)
+ testing.expectf(t, ec.pt_equal(&p, &expected) == 1, "sc: %s actual: %v expected: %v", v.scalar, &p, &expected)
+ }
+}
+
+@(test)
+test_p256_s11n_sec_identity ::proc(t: ^testing.T) {
+ p: ec.Point_p256r1
+
+ ec.pt_generator(&p)
+ ok := ec.pt_set_sec_bytes(&p, []byte{0x00})
+ testing.expect(t, ok)
+ testing.expectf(t, ec.pt_is_identity(&p) == 1, "%v", p)
+
+ b := []byte{0xff}
+ ok = ec.pt_sec_bytes(b, &p, true)
+ testing.expect(t, ok)
+ testing.expect(t, b[0] == 0x00)
+
+ b = []byte{0xff}
+ ok = ec.pt_sec_bytes(b, &p, false)
+ testing.expect(t, ok)
+ testing.expect(t, b[0] == 0x00)
+}
+
+@(test)
+test_p256_s11n_sec_generator ::proc(t: ^testing.T) {
+ p, g: ec.Point_p256r1
+
+ ec.pt_generator(&g)
+ ec.pt_identity(&p)
+
+ b: [65]byte
+ ok := ec.pt_sec_bytes(b[:], &g, false)
+ testing.expect(t, ok)
+ s := (string)(hex.encode(b[:], context.temp_allocator))
+ testing.expectf(t, s == P256_G_UNCOMPRESSED, "g: %v bytes: %v, %v", g, P256_G_UNCOMPRESSED, s)
+
+ ok = ec.pt_set_sec_bytes(&p, b[:])
+ testing.expectf(t, ok, "%s", s)
+ testing.expect(t, ec.pt_equal(&g, &p) == 1)
+}
diff --git a/vendor/x11/xlib/xlib_keysym.odin b/vendor/x11/xlib/xlib_keysym.odin
index 61284c723..267b77b1c 100644
--- a/vendor/x11/xlib/xlib_keysym.odin
+++ b/vendor/x11/xlib/xlib_keysym.odin
@@ -1,7 +1,7 @@
#+build linux, freebsd, openbsd
package xlib
-KeySym :: enum u32 {
+KeySym :: enum uint {
XK_BackSpace = 0xff08, /* Back space, back char */
XK_Tab = 0xff09,
XK_Linefeed = 0xff0a, /* Linefeed, LF */
diff --git a/vendor/x11/xlib/xlib_procs.odin b/vendor/x11/xlib/xlib_procs.odin
index 42e49ea02..3886bbead 100644
--- a/vendor/x11/xlib/xlib_procs.odin
+++ b/vendor/x11/xlib/xlib_procs.odin
@@ -2068,7 +2068,7 @@ foreign xlib {
Xutf8LookupString :: proc(
ic: XIC,
event: ^XKeyPressedEvent,
- buffer_return: ^cstring,
+ buffer_return: cstring,
bytes_buffer: i32,
keysym_return: ^KeySym,
status_return: ^LookupStringStatus,