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, "") or_return + write_string(i, buf, "") 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.. (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.. 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" +// 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 + + a += b + d ~= a + d = bits.rotate_left32(d, 16) + + c += d + b ~= c + b = bits.rotate_left32(b, 12) + + a += b + d ~= a + d = bits.rotate_left32(d, 8) + + c += d + b ~= c + b = bits.rotate_left32(b, 7) + + return a, b, c, d +} + 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 + + + // 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. + + 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]) + 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] + // First column round that depends on the counter + p0, p4, p8, p12 := quarter_round(_chacha20.SIGMA_0, x[4], x[8], x[12]) - for i := _chacha20.ROUNDS; i > 0; i = i - 2 { - // Even when forcing inlining manually inlining all of - // these is decently faster. + // 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) - // 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) + 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) - // 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, 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) + 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) - // 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, 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.. 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 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 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 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 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,63 +47,37 @@ bench_ecdh :: proc() { ) } - scalar_bp, scalar := bench_x25519() - append_tbl(&tbl, "X25519", scalar_bp, scalar) + for algo in ecdh.Curve { + if algo == .Invalid { + continue + } + algo_name := ecdh.CURVE_NAMES[algo] - scalar_bp, scalar = bench_x448() - append_tbl(&tbl, "X448", scalar_bp, scalar) + 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) + } 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[:]) - } - sc = time.tick_since(start) / ECDH_ITERS - - return -} - @(private = "file") bench_dsa :: proc() { tbl: table.Table 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,