aboutsummaryrefslogtreecommitdiff
path: root/src/crypto/fipsmodule/ec
diff options
context:
space:
mode:
Diffstat (limited to 'src/crypto/fipsmodule/ec')
-rw-r--r--src/crypto/fipsmodule/ec/asm/p256-armv8-asm.pl1676
-rwxr-xr-xsrc/crypto/fipsmodule/ec/asm/p256-x86_64-asm.pl4158
-rw-r--r--src/crypto/fipsmodule/ec/asm/p256_beeu-armv8-asm.pl455
-rw-r--r--src/crypto/fipsmodule/ec/asm/p256_beeu-x86_64-asm.pl403
-rw-r--r--src/crypto/fipsmodule/ec/ec.c1268
-rw-r--r--src/crypto/fipsmodule/ec/ec_key.c546
-rw-r--r--src/crypto/fipsmodule/ec/ec_montgomery.c524
-rw-r--r--src/crypto/fipsmodule/ec/ec_scalar_base_mult_tests.txt3101
-rw-r--r--src/crypto/fipsmodule/ec/ec_test.cc1430
-rw-r--r--src/crypto/fipsmodule/ec/felem.c100
-rw-r--r--src/crypto/fipsmodule/ec/internal.h794
-rw-r--r--src/crypto/fipsmodule/ec/make_ec_scalar_base_mult_tests.go62
-rw-r--r--src/crypto/fipsmodule/ec/make_p256-nistz-tests.go234
-rw-r--r--src/crypto/fipsmodule/ec/make_tables.go408
-rw-r--r--src/crypto/fipsmodule/ec/oct.c358
-rw-r--r--src/crypto/fipsmodule/ec/p224-64.c1164
-rw-r--r--src/crypto/fipsmodule/ec/p256-nistz-table.h9497
-rw-r--r--src/crypto/fipsmodule/ec/p256-nistz.c640
-rw-r--r--src/crypto/fipsmodule/ec/p256-nistz.h145
-rw-r--r--src/crypto/fipsmodule/ec/p256-nistz_test.cc582
-rw-r--r--src/crypto/fipsmodule/ec/p256-nistz_tests.txt1548
-rw-r--r--src/crypto/fipsmodule/ec/p256.c751
-rw-r--r--src/crypto/fipsmodule/ec/p256_table.h297
-rw-r--r--src/crypto/fipsmodule/ec/scalar.c169
-rw-r--r--src/crypto/fipsmodule/ec/simple.c352
-rw-r--r--src/crypto/fipsmodule/ec/simple_mul.c269
-rw-r--r--src/crypto/fipsmodule/ec/util.c255
-rw-r--r--src/crypto/fipsmodule/ec/wnaf.c269
28 files changed, 31455 insertions, 0 deletions
diff --git a/src/crypto/fipsmodule/ec/asm/p256-armv8-asm.pl b/src/crypto/fipsmodule/ec/asm/p256-armv8-asm.pl
new file mode 100644
index 0000000..95dc4c8
--- /dev/null
+++ b/src/crypto/fipsmodule/ec/asm/p256-armv8-asm.pl
@@ -0,0 +1,1676 @@
+#! /usr/bin/env perl
+# Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the OpenSSL license (the "License"). You may not use
+# this file except in compliance with the License. You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+
+
+# ====================================================================
+# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+#
+# ECP_NISTZ256 module for ARMv8.
+#
+# February 2015.
+#
+# Original ECP_NISTZ256 submission targeting x86_64 is detailed in
+# http://eprint.iacr.org/2013/816.
+#
+# with/without -DECP_NISTZ256_ASM
+# Apple A7 +190-360%
+# Cortex-A53 +190-400%
+# Cortex-A57 +190-350%
+# Denver +230-400%
+#
+# Ranges denote minimum and maximum improvement coefficients depending
+# on benchmark. Lower coefficients are for ECDSA sign, server-side
+# operation. Keep in mind that +400% means 5x improvement.
+
+# The first two arguments should always be the flavour and output file path.
+if ($#ARGV < 1) { die "Not enough arguments provided.
+ Two arguments are necessary: the flavour and the output file path."; }
+
+$flavour = shift;
+$output = shift;
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../../perlasm/arm-xlate.pl" and -f $xlate) or
+die "can't locate arm-xlate.pl";
+
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
+
+{
+my ($rp,$ap,$bp,$bi,$a0,$a1,$a2,$a3,$t0,$t1,$t2,$t3,$poly1,$poly3,
+ $acc0,$acc1,$acc2,$acc3,$acc4,$acc5) =
+ map("x$_",(0..17,19,20));
+
+my ($acc6,$acc7)=($ap,$bp); # used in __ecp_nistz256_sqr_mont
+
+$code.=<<___;
+#include "openssl/arm_arch.h"
+
+.section .rodata
+.align 5
+.Lpoly:
+.quad 0xffffffffffffffff,0x00000000ffffffff,0x0000000000000000,0xffffffff00000001
+.LRR: // 2^512 mod P precomputed for NIST P256 polynomial
+.quad 0x0000000000000003,0xfffffffbffffffff,0xfffffffffffffffe,0x00000004fffffffd
+.Lone_mont:
+.quad 0x0000000000000001,0xffffffff00000000,0xffffffffffffffff,0x00000000fffffffe
+.Lone:
+.quad 1,0,0,0
+.Lord:
+.quad 0xf3b9cac2fc632551,0xbce6faada7179e84,0xffffffffffffffff,0xffffffff00000000
+.LordK:
+.quad 0xccd1c8aaee00bc4f
+.asciz "ECP_NISTZ256 for ARMv8, CRYPTOGAMS by <appro\@openssl.org>"
+.text
+
+// void ecp_nistz256_mul_mont(BN_ULONG x0[4],const BN_ULONG x1[4],
+// const BN_ULONG x2[4]);
+.globl ecp_nistz256_mul_mont
+.type ecp_nistz256_mul_mont,%function
+.align 4
+ecp_nistz256_mul_mont:
+ AARCH64_SIGN_LINK_REGISTER
+ stp x29,x30,[sp,#-32]!
+ add x29,sp,#0
+ stp x19,x20,[sp,#16]
+
+ ldr $bi,[$bp] // bp[0]
+ ldp $a0,$a1,[$ap]
+ ldp $a2,$a3,[$ap,#16]
+ adrp $poly3,:pg_hi21:.Lpoly
+ add $poly3,$poly3,:lo12:.Lpoly
+ ldr $poly1,[$poly3,#8]
+ ldr $poly3,[$poly3,#24]
+
+ bl __ecp_nistz256_mul_mont
+
+ ldp x19,x20,[sp,#16]
+ ldp x29,x30,[sp],#32
+ AARCH64_VALIDATE_LINK_REGISTER
+ ret
+.size ecp_nistz256_mul_mont,.-ecp_nistz256_mul_mont
+
+// void ecp_nistz256_sqr_mont(BN_ULONG x0[4],const BN_ULONG x1[4]);
+.globl ecp_nistz256_sqr_mont
+.type ecp_nistz256_sqr_mont,%function
+.align 4
+ecp_nistz256_sqr_mont:
+ AARCH64_SIGN_LINK_REGISTER
+ stp x29,x30,[sp,#-32]!
+ add x29,sp,#0
+ stp x19,x20,[sp,#16]
+
+ ldp $a0,$a1,[$ap]
+ ldp $a2,$a3,[$ap,#16]
+ adrp $poly3,:pg_hi21:.Lpoly
+ add $poly3,$poly3,:lo12:.Lpoly
+ ldr $poly1,[$poly3,#8]
+ ldr $poly3,[$poly3,#24]
+
+ bl __ecp_nistz256_sqr_mont
+
+ ldp x19,x20,[sp,#16]
+ ldp x29,x30,[sp],#32
+ AARCH64_VALIDATE_LINK_REGISTER
+ ret
+.size ecp_nistz256_sqr_mont,.-ecp_nistz256_sqr_mont
+
+// void ecp_nistz256_div_by_2(BN_ULONG x0[4],const BN_ULONG x1[4]);
+.globl ecp_nistz256_div_by_2
+.type ecp_nistz256_div_by_2,%function
+.align 4
+ecp_nistz256_div_by_2:
+ AARCH64_SIGN_LINK_REGISTER
+ stp x29,x30,[sp,#-16]!
+ add x29,sp,#0
+
+ ldp $acc0,$acc1,[$ap]
+ ldp $acc2,$acc3,[$ap,#16]
+ adrp $poly3,:pg_hi21:.Lpoly
+ add $poly3,$poly3,:lo12:.Lpoly
+ ldr $poly1,[$poly3,#8]
+ ldr $poly3,[$poly3,#24]
+
+ bl __ecp_nistz256_div_by_2
+
+ ldp x29,x30,[sp],#16
+ AARCH64_VALIDATE_LINK_REGISTER
+ ret
+.size ecp_nistz256_div_by_2,.-ecp_nistz256_div_by_2
+
+// void ecp_nistz256_mul_by_2(BN_ULONG x0[4],const BN_ULONG x1[4]);
+.globl ecp_nistz256_mul_by_2
+.type ecp_nistz256_mul_by_2,%function
+.align 4
+ecp_nistz256_mul_by_2:
+ AARCH64_SIGN_LINK_REGISTER
+ stp x29,x30,[sp,#-16]!
+ add x29,sp,#0
+
+ ldp $acc0,$acc1,[$ap]
+ ldp $acc2,$acc3,[$ap,#16]
+ adrp $poly3,:pg_hi21:.Lpoly
+ add $poly3,$poly3,:lo12:.Lpoly
+ ldr $poly1,[$poly3,#8]
+ ldr $poly3,[$poly3,#24]
+ mov $t0,$acc0
+ mov $t1,$acc1
+ mov $t2,$acc2
+ mov $t3,$acc3
+
+ bl __ecp_nistz256_add_to // ret = a+a // 2*a
+
+ ldp x29,x30,[sp],#16
+ AARCH64_VALIDATE_LINK_REGISTER
+ ret
+.size ecp_nistz256_mul_by_2,.-ecp_nistz256_mul_by_2
+
+// void ecp_nistz256_mul_by_3(BN_ULONG x0[4],const BN_ULONG x1[4]);
+.globl ecp_nistz256_mul_by_3
+.type ecp_nistz256_mul_by_3,%function
+.align 4
+ecp_nistz256_mul_by_3:
+ AARCH64_SIGN_LINK_REGISTER
+ stp x29,x30,[sp,#-16]!
+ add x29,sp,#0
+
+ ldp $acc0,$acc1,[$ap]
+ ldp $acc2,$acc3,[$ap,#16]
+ adrp $poly3,:pg_hi21:.Lpoly
+ add $poly3,$poly3,:lo12:.Lpoly
+ ldr $poly1,[$poly3,#8]
+ ldr $poly3,[$poly3,#24]
+ mov $t0,$acc0
+ mov $t1,$acc1
+ mov $t2,$acc2
+ mov $t3,$acc3
+ mov $a0,$acc0
+ mov $a1,$acc1
+ mov $a2,$acc2
+ mov $a3,$acc3
+
+ bl __ecp_nistz256_add_to // ret = a+a // 2*a
+
+ mov $t0,$a0
+ mov $t1,$a1
+ mov $t2,$a2
+ mov $t3,$a3
+
+ bl __ecp_nistz256_add_to // ret += a // 2*a+a=3*a
+
+ ldp x29,x30,[sp],#16
+ AARCH64_VALIDATE_LINK_REGISTER
+ ret
+.size ecp_nistz256_mul_by_3,.-ecp_nistz256_mul_by_3
+
+// void ecp_nistz256_sub(BN_ULONG x0[4],const BN_ULONG x1[4],
+// const BN_ULONG x2[4]);
+.globl ecp_nistz256_sub
+.type ecp_nistz256_sub,%function
+.align 4
+ecp_nistz256_sub:
+ AARCH64_SIGN_LINK_REGISTER
+ stp x29,x30,[sp,#-16]!
+ add x29,sp,#0
+
+ ldp $acc0,$acc1,[$ap]
+ ldp $acc2,$acc3,[$ap,#16]
+ adrp $poly3,:pg_hi21:.Lpoly
+ add $poly3,$poly3,:lo12:.Lpoly
+ ldr $poly1,[$poly3,#8]
+ ldr $poly3,[$poly3,#24]
+
+ bl __ecp_nistz256_sub_from
+
+ ldp x29,x30,[sp],#16
+ AARCH64_VALIDATE_LINK_REGISTER
+ ret
+.size ecp_nistz256_sub,.-ecp_nistz256_sub
+
+// void ecp_nistz256_neg(BN_ULONG x0[4],const BN_ULONG x1[4]);
+.globl ecp_nistz256_neg
+.type ecp_nistz256_neg,%function
+.align 4
+ecp_nistz256_neg:
+ AARCH64_SIGN_LINK_REGISTER
+ stp x29,x30,[sp,#-16]!
+ add x29,sp,#0
+
+ mov $bp,$ap
+ mov $acc0,xzr // a = 0
+ mov $acc1,xzr
+ mov $acc2,xzr
+ mov $acc3,xzr
+ adrp $poly3,:pg_hi21:.Lpoly
+ add $poly3,$poly3,:lo12:.Lpoly
+ ldr $poly1,[$poly3,#8]
+ ldr $poly3,[$poly3,#24]
+
+ bl __ecp_nistz256_sub_from
+
+ ldp x29,x30,[sp],#16
+ AARCH64_VALIDATE_LINK_REGISTER
+ ret
+.size ecp_nistz256_neg,.-ecp_nistz256_neg
+
+// note that __ecp_nistz256_mul_mont expects a[0-3] input pre-loaded
+// to $a0-$a3 and b[0] - to $bi
+.type __ecp_nistz256_mul_mont,%function
+.align 4
+__ecp_nistz256_mul_mont:
+ mul $acc0,$a0,$bi // a[0]*b[0]
+ umulh $t0,$a0,$bi
+
+ mul $acc1,$a1,$bi // a[1]*b[0]
+ umulh $t1,$a1,$bi
+
+ mul $acc2,$a2,$bi // a[2]*b[0]
+ umulh $t2,$a2,$bi
+
+ mul $acc3,$a3,$bi // a[3]*b[0]
+ umulh $t3,$a3,$bi
+ ldr $bi,[$bp,#8] // b[1]
+
+ adds $acc1,$acc1,$t0 // accumulate high parts of multiplication
+ lsl $t0,$acc0,#32
+ adcs $acc2,$acc2,$t1
+ lsr $t1,$acc0,#32
+ adcs $acc3,$acc3,$t2
+ adc $acc4,xzr,$t3
+ mov $acc5,xzr
+___
+for($i=1;$i<4;$i++) {
+ # Reduction iteration is normally performed by accumulating
+ # result of multiplication of modulus by "magic" digit [and
+ # omitting least significant word, which is guaranteed to
+ # be 0], but thanks to special form of modulus and "magic"
+ # digit being equal to least significant word, it can be
+ # performed with additions and subtractions alone. Indeed:
+ #
+ # ffff0001.00000000.0000ffff.ffffffff
+ # * abcdefgh
+ # + xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx.abcdefgh
+ #
+ # Now observing that ff..ff*x = (2^n-1)*x = 2^n*x-x, we
+ # rewrite above as:
+ #
+ # xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx.abcdefgh
+ # + abcdefgh.abcdefgh.0000abcd.efgh0000.00000000
+ # - 0000abcd.efgh0000.00000000.00000000.abcdefgh
+ #
+ # or marking redundant operations:
+ #
+ # xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx.--------
+ # + abcdefgh.abcdefgh.0000abcd.efgh0000.--------
+ # - 0000abcd.efgh0000.--------.--------.--------
+
+$code.=<<___;
+ subs $t2,$acc0,$t0 // "*0xffff0001"
+ sbc $t3,$acc0,$t1
+ adds $acc0,$acc1,$t0 // +=acc[0]<<96 and omit acc[0]
+ mul $t0,$a0,$bi // lo(a[0]*b[i])
+ adcs $acc1,$acc2,$t1
+ mul $t1,$a1,$bi // lo(a[1]*b[i])
+ adcs $acc2,$acc3,$t2 // +=acc[0]*0xffff0001
+ mul $t2,$a2,$bi // lo(a[2]*b[i])
+ adcs $acc3,$acc4,$t3
+ mul $t3,$a3,$bi // lo(a[3]*b[i])
+ adc $acc4,$acc5,xzr
+
+ adds $acc0,$acc0,$t0 // accumulate low parts of multiplication
+ umulh $t0,$a0,$bi // hi(a[0]*b[i])
+ adcs $acc1,$acc1,$t1
+ umulh $t1,$a1,$bi // hi(a[1]*b[i])
+ adcs $acc2,$acc2,$t2
+ umulh $t2,$a2,$bi // hi(a[2]*b[i])
+ adcs $acc3,$acc3,$t3
+ umulh $t3,$a3,$bi // hi(a[3]*b[i])
+ adc $acc4,$acc4,xzr
+___
+$code.=<<___ if ($i<3);
+ ldr $bi,[$bp,#8*($i+1)] // b[$i+1]
+___
+$code.=<<___;
+ adds $acc1,$acc1,$t0 // accumulate high parts of multiplication
+ lsl $t0,$acc0,#32
+ adcs $acc2,$acc2,$t1
+ lsr $t1,$acc0,#32
+ adcs $acc3,$acc3,$t2
+ adcs $acc4,$acc4,$t3
+ adc $acc5,xzr,xzr
+___
+}
+$code.=<<___;
+ // last reduction
+ subs $t2,$acc0,$t0 // "*0xffff0001"
+ sbc $t3,$acc0,$t1
+ adds $acc0,$acc1,$t0 // +=acc[0]<<96 and omit acc[0]
+ adcs $acc1,$acc2,$t1
+ adcs $acc2,$acc3,$t2 // +=acc[0]*0xffff0001
+ adcs $acc3,$acc4,$t3
+ adc $acc4,$acc5,xzr
+
+ adds $t0,$acc0,#1 // subs $t0,$acc0,#-1 // tmp = ret-modulus
+ sbcs $t1,$acc1,$poly1
+ sbcs $t2,$acc2,xzr
+ sbcs $t3,$acc3,$poly3
+ sbcs xzr,$acc4,xzr // did it borrow?
+
+ csel $acc0,$acc0,$t0,lo // ret = borrow ? ret : ret-modulus
+ csel $acc1,$acc1,$t1,lo
+ csel $acc2,$acc2,$t2,lo
+ stp $acc0,$acc1,[$rp]
+ csel $acc3,$acc3,$t3,lo
+ stp $acc2,$acc3,[$rp,#16]
+
+ ret
+.size __ecp_nistz256_mul_mont,.-__ecp_nistz256_mul_mont
+
+// note that __ecp_nistz256_sqr_mont expects a[0-3] input pre-loaded
+// to $a0-$a3
+.type __ecp_nistz256_sqr_mont,%function
+.align 4
+__ecp_nistz256_sqr_mont:
+ // | | | | | |a1*a0| |
+ // | | | | |a2*a0| | |
+ // | |a3*a2|a3*a0| | | |
+ // | | | |a2*a1| | | |
+ // | | |a3*a1| | | | |
+ // *| | | | | | | | 2|
+ // +|a3*a3|a2*a2|a1*a1|a0*a0|
+ // |--+--+--+--+--+--+--+--|
+ // |A7|A6|A5|A4|A3|A2|A1|A0|, where Ax is $accx, i.e. follow $accx
+ //
+ // "can't overflow" below mark carrying into high part of
+ // multiplication result, which can't overflow, because it
+ // can never be all ones.
+
+ mul $acc1,$a1,$a0 // a[1]*a[0]
+ umulh $t1,$a1,$a0
+ mul $acc2,$a2,$a0 // a[2]*a[0]
+ umulh $t2,$a2,$a0
+ mul $acc3,$a3,$a0 // a[3]*a[0]
+ umulh $acc4,$a3,$a0
+
+ adds $acc2,$acc2,$t1 // accumulate high parts of multiplication
+ mul $t0,$a2,$a1 // a[2]*a[1]
+ umulh $t1,$a2,$a1
+ adcs $acc3,$acc3,$t2
+ mul $t2,$a3,$a1 // a[3]*a[1]
+ umulh $t3,$a3,$a1
+ adc $acc4,$acc4,xzr // can't overflow
+
+ mul $acc5,$a3,$a2 // a[3]*a[2]
+ umulh $acc6,$a3,$a2
+
+ adds $t1,$t1,$t2 // accumulate high parts of multiplication
+ mul $acc0,$a0,$a0 // a[0]*a[0]
+ adc $t2,$t3,xzr // can't overflow
+
+ adds $acc3,$acc3,$t0 // accumulate low parts of multiplication
+ umulh $a0,$a0,$a0
+ adcs $acc4,$acc4,$t1
+ mul $t1,$a1,$a1 // a[1]*a[1]
+ adcs $acc5,$acc5,$t2
+ umulh $a1,$a1,$a1
+ adc $acc6,$acc6,xzr // can't overflow
+
+ adds $acc1,$acc1,$acc1 // acc[1-6]*=2
+ mul $t2,$a2,$a2 // a[2]*a[2]
+ adcs $acc2,$acc2,$acc2
+ umulh $a2,$a2,$a2
+ adcs $acc3,$acc3,$acc3
+ mul $t3,$a3,$a3 // a[3]*a[3]
+ adcs $acc4,$acc4,$acc4
+ umulh $a3,$a3,$a3
+ adcs $acc5,$acc5,$acc5
+ adcs $acc6,$acc6,$acc6
+ adc $acc7,xzr,xzr
+
+ adds $acc1,$acc1,$a0 // +a[i]*a[i]
+ adcs $acc2,$acc2,$t1
+ adcs $acc3,$acc3,$a1
+ adcs $acc4,$acc4,$t2
+ adcs $acc5,$acc5,$a2
+ lsl $t0,$acc0,#32
+ adcs $acc6,$acc6,$t3
+ lsr $t1,$acc0,#32
+ adc $acc7,$acc7,$a3
+___
+for($i=0;$i<3;$i++) { # reductions, see commentary in
+ # multiplication for details
+$code.=<<___;
+ subs $t2,$acc0,$t0 // "*0xffff0001"
+ sbc $t3,$acc0,$t1
+ adds $acc0,$acc1,$t0 // +=acc[0]<<96 and omit acc[0]
+ adcs $acc1,$acc2,$t1
+ lsl $t0,$acc0,#32
+ adcs $acc2,$acc3,$t2 // +=acc[0]*0xffff0001
+ lsr $t1,$acc0,#32
+ adc $acc3,$t3,xzr // can't overflow
+___
+}
+$code.=<<___;
+ subs $t2,$acc0,$t0 // "*0xffff0001"
+ sbc $t3,$acc0,$t1
+ adds $acc0,$acc1,$t0 // +=acc[0]<<96 and omit acc[0]
+ adcs $acc1,$acc2,$t1
+ adcs $acc2,$acc3,$t2 // +=acc[0]*0xffff0001
+ adc $acc3,$t3,xzr // can't overflow
+
+ adds $acc0,$acc0,$acc4 // accumulate upper half
+ adcs $acc1,$acc1,$acc5
+ adcs $acc2,$acc2,$acc6
+ adcs $acc3,$acc3,$acc7
+ adc $acc4,xzr,xzr
+
+ adds $t0,$acc0,#1 // subs $t0,$acc0,#-1 // tmp = ret-modulus
+ sbcs $t1,$acc1,$poly1
+ sbcs $t2,$acc2,xzr
+ sbcs $t3,$acc3,$poly3
+ sbcs xzr,$acc4,xzr // did it borrow?
+
+ csel $acc0,$acc0,$t0,lo // ret = borrow ? ret : ret-modulus
+ csel $acc1,$acc1,$t1,lo
+ csel $acc2,$acc2,$t2,lo
+ stp $acc0,$acc1,[$rp]
+ csel $acc3,$acc3,$t3,lo
+ stp $acc2,$acc3,[$rp,#16]
+
+ ret
+.size __ecp_nistz256_sqr_mont,.-__ecp_nistz256_sqr_mont
+
+// Note that __ecp_nistz256_add_to expects both input vectors pre-loaded to
+// $a0-$a3 and $t0-$t3. This is done because it's used in multiple
+// contexts, e.g. in multiplication by 2 and 3...
+.type __ecp_nistz256_add_to,%function
+.align 4
+__ecp_nistz256_add_to:
+ adds $acc0,$acc0,$t0 // ret = a+b
+ adcs $acc1,$acc1,$t1
+ adcs $acc2,$acc2,$t2
+ adcs $acc3,$acc3,$t3
+ adc $ap,xzr,xzr // zap $ap
+
+ adds $t0,$acc0,#1 // subs $t0,$a0,#-1 // tmp = ret-modulus
+ sbcs $t1,$acc1,$poly1
+ sbcs $t2,$acc2,xzr
+ sbcs $t3,$acc3,$poly3
+ sbcs xzr,$ap,xzr // did subtraction borrow?
+
+ csel $acc0,$acc0,$t0,lo // ret = borrow ? ret : ret-modulus
+ csel $acc1,$acc1,$t1,lo
+ csel $acc2,$acc2,$t2,lo
+ stp $acc0,$acc1,[$rp]
+ csel $acc3,$acc3,$t3,lo
+ stp $acc2,$acc3,[$rp,#16]
+
+ ret
+.size __ecp_nistz256_add_to,.-__ecp_nistz256_add_to
+
+.type __ecp_nistz256_sub_from,%function
+.align 4
+__ecp_nistz256_sub_from:
+ ldp $t0,$t1,[$bp]
+ ldp $t2,$t3,[$bp,#16]
+ subs $acc0,$acc0,$t0 // ret = a-b
+ sbcs $acc1,$acc1,$t1
+ sbcs $acc2,$acc2,$t2
+ sbcs $acc3,$acc3,$t3
+ sbc $ap,xzr,xzr // zap $ap
+
+ subs $t0,$acc0,#1 // adds $t0,$a0,#-1 // tmp = ret+modulus
+ adcs $t1,$acc1,$poly1
+ adcs $t2,$acc2,xzr
+ adc $t3,$acc3,$poly3
+ cmp $ap,xzr // did subtraction borrow?
+
+ csel $acc0,$acc0,$t0,eq // ret = borrow ? ret+modulus : ret
+ csel $acc1,$acc1,$t1,eq
+ csel $acc2,$acc2,$t2,eq
+ stp $acc0,$acc1,[$rp]
+ csel $acc3,$acc3,$t3,eq
+ stp $acc2,$acc3,[$rp,#16]
+
+ ret
+.size __ecp_nistz256_sub_from,.-__ecp_nistz256_sub_from
+
+.type __ecp_nistz256_sub_morf,%function
+.align 4
+__ecp_nistz256_sub_morf:
+ ldp $t0,$t1,[$bp]
+ ldp $t2,$t3,[$bp,#16]
+ subs $acc0,$t0,$acc0 // ret = b-a
+ sbcs $acc1,$t1,$acc1
+ sbcs $acc2,$t2,$acc2
+ sbcs $acc3,$t3,$acc3
+ sbc $ap,xzr,xzr // zap $ap
+
+ subs $t0,$acc0,#1 // adds $t0,$a0,#-1 // tmp = ret+modulus
+ adcs $t1,$acc1,$poly1
+ adcs $t2,$acc2,xzr
+ adc $t3,$acc3,$poly3
+ cmp $ap,xzr // did subtraction borrow?
+
+ csel $acc0,$acc0,$t0,eq // ret = borrow ? ret+modulus : ret
+ csel $acc1,$acc1,$t1,eq
+ csel $acc2,$acc2,$t2,eq
+ stp $acc0,$acc1,[$rp]
+ csel $acc3,$acc3,$t3,eq
+ stp $acc2,$acc3,[$rp,#16]
+
+ ret
+.size __ecp_nistz256_sub_morf,.-__ecp_nistz256_sub_morf
+
+.type __ecp_nistz256_div_by_2,%function
+.align 4
+__ecp_nistz256_div_by_2:
+ subs $t0,$acc0,#1 // adds $t0,$a0,#-1 // tmp = a+modulus
+ adcs $t1,$acc1,$poly1
+ adcs $t2,$acc2,xzr
+ adcs $t3,$acc3,$poly3
+ adc $ap,xzr,xzr // zap $ap
+ tst $acc0,#1 // is a even?
+
+ csel $acc0,$acc0,$t0,eq // ret = even ? a : a+modulus
+ csel $acc1,$acc1,$t1,eq
+ csel $acc2,$acc2,$t2,eq
+ csel $acc3,$acc3,$t3,eq
+ csel $ap,xzr,$ap,eq
+
+ lsr $acc0,$acc0,#1 // ret >>= 1
+ orr $acc0,$acc0,$acc1,lsl#63
+ lsr $acc1,$acc1,#1
+ orr $acc1,$acc1,$acc2,lsl#63
+ lsr $acc2,$acc2,#1
+ orr $acc2,$acc2,$acc3,lsl#63
+ lsr $acc3,$acc3,#1
+ stp $acc0,$acc1,[$rp]
+ orr $acc3,$acc3,$ap,lsl#63
+ stp $acc2,$acc3,[$rp,#16]
+
+ ret
+.size __ecp_nistz256_div_by_2,.-__ecp_nistz256_div_by_2
+___
+########################################################################
+# following subroutines are "literal" implementation of those found in
+# ecp_nistz256.c
+#
+########################################################################
+# void ecp_nistz256_point_double(P256_POINT *out,const P256_POINT *inp);
+#
+{
+my ($S,$M,$Zsqr,$tmp0)=map(32*$_,(0..3));
+# above map() describes stack layout with 4 temporary
+# 256-bit vectors on top.
+my ($rp_real,$ap_real) = map("x$_",(21,22));
+
+$code.=<<___;
+.globl ecp_nistz256_point_double
+.type ecp_nistz256_point_double,%function
+.align 5
+ecp_nistz256_point_double:
+ AARCH64_SIGN_LINK_REGISTER
+ stp x29,x30,[sp,#-96]!
+ add x29,sp,#0
+ stp x19,x20,[sp,#16]
+ stp x21,x22,[sp,#32]
+ sub sp,sp,#32*4
+
+.Ldouble_shortcut:
+ ldp $acc0,$acc1,[$ap,#32]
+ mov $rp_real,$rp
+ ldp $acc2,$acc3,[$ap,#48]
+ mov $ap_real,$ap
+ adrp $poly3,:pg_hi21:.Lpoly
+ add $poly3,$poly3,:lo12:.Lpoly
+ ldr $poly1,[$poly3,#8]
+ mov $t0,$acc0
+ ldr $poly3,[$poly3,#24]
+ mov $t1,$acc1
+ ldp $a0,$a1,[$ap_real,#64] // forward load for p256_sqr_mont
+ mov $t2,$acc2
+ mov $t3,$acc3
+ ldp $a2,$a3,[$ap_real,#64+16]
+ add $rp,sp,#$S
+ bl __ecp_nistz256_add_to // p256_mul_by_2(S, in_y);
+
+ add $rp,sp,#$Zsqr
+ bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Zsqr, in_z);
+
+ ldp $t0,$t1,[$ap_real]
+ ldp $t2,$t3,[$ap_real,#16]
+ mov $a0,$acc0 // put Zsqr aside for p256_sub
+ mov $a1,$acc1
+ mov $a2,$acc2
+ mov $a3,$acc3
+ add $rp,sp,#$M
+ bl __ecp_nistz256_add_to // p256_add(M, Zsqr, in_x);
+
+ add $bp,$ap_real,#0
+ mov $acc0,$a0 // restore Zsqr
+ mov $acc1,$a1
+ ldp $a0,$a1,[sp,#$S] // forward load for p256_sqr_mont
+ mov $acc2,$a2
+ mov $acc3,$a3
+ ldp $a2,$a3,[sp,#$S+16]
+ add $rp,sp,#$Zsqr
+ bl __ecp_nistz256_sub_morf // p256_sub(Zsqr, in_x, Zsqr);
+
+ add $rp,sp,#$S
+ bl __ecp_nistz256_sqr_mont // p256_sqr_mont(S, S);
+
+ ldr $bi,[$ap_real,#32]
+ ldp $a0,$a1,[$ap_real,#64]
+ ldp $a2,$a3,[$ap_real,#64+16]
+ add $bp,$ap_real,#32
+ add $rp,sp,#$tmp0
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(tmp0, in_z, in_y);
+
+ mov $t0,$acc0
+ mov $t1,$acc1
+ ldp $a0,$a1,[sp,#$S] // forward load for p256_sqr_mont
+ mov $t2,$acc2
+ mov $t3,$acc3
+ ldp $a2,$a3,[sp,#$S+16]
+ add $rp,$rp_real,#64
+ bl __ecp_nistz256_add_to // p256_mul_by_2(res_z, tmp0);
+
+ add $rp,sp,#$tmp0
+ bl __ecp_nistz256_sqr_mont // p256_sqr_mont(tmp0, S);
+
+ ldr $bi,[sp,#$Zsqr] // forward load for p256_mul_mont
+ ldp $a0,$a1,[sp,#$M]
+ ldp $a2,$a3,[sp,#$M+16]
+ add $rp,$rp_real,#32
+ bl __ecp_nistz256_div_by_2 // p256_div_by_2(res_y, tmp0);
+
+ add $bp,sp,#$Zsqr
+ add $rp,sp,#$M
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(M, M, Zsqr);
+
+ mov $t0,$acc0 // duplicate M
+ mov $t1,$acc1
+ mov $t2,$acc2
+ mov $t3,$acc3
+ mov $a0,$acc0 // put M aside
+ mov $a1,$acc1
+ mov $a2,$acc2
+ mov $a3,$acc3
+ add $rp,sp,#$M
+ bl __ecp_nistz256_add_to
+ mov $t0,$a0 // restore M
+ mov $t1,$a1
+ ldr $bi,[$ap_real] // forward load for p256_mul_mont
+ mov $t2,$a2
+ ldp $a0,$a1,[sp,#$S]
+ mov $t3,$a3
+ ldp $a2,$a3,[sp,#$S+16]
+ bl __ecp_nistz256_add_to // p256_mul_by_3(M, M);
+
+ add $bp,$ap_real,#0
+ add $rp,sp,#$S
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(S, S, in_x);
+
+ mov $t0,$acc0
+ mov $t1,$acc1
+ ldp $a0,$a1,[sp,#$M] // forward load for p256_sqr_mont
+ mov $t2,$acc2
+ mov $t3,$acc3
+ ldp $a2,$a3,[sp,#$M+16]
+ add $rp,sp,#$tmp0
+ bl __ecp_nistz256_add_to // p256_mul_by_2(tmp0, S);
+
+ add $rp,$rp_real,#0
+ bl __ecp_nistz256_sqr_mont // p256_sqr_mont(res_x, M);
+
+ add $bp,sp,#$tmp0
+ bl __ecp_nistz256_sub_from // p256_sub(res_x, res_x, tmp0);
+
+ add $bp,sp,#$S
+ add $rp,sp,#$S
+ bl __ecp_nistz256_sub_morf // p256_sub(S, S, res_x);
+
+ ldr $bi,[sp,#$M]
+ mov $a0,$acc0 // copy S
+ mov $a1,$acc1
+ mov $a2,$acc2
+ mov $a3,$acc3
+ add $bp,sp,#$M
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(S, S, M);
+
+ add $bp,$rp_real,#32
+ add $rp,$rp_real,#32
+ bl __ecp_nistz256_sub_from // p256_sub(res_y, S, res_y);
+
+ add sp,x29,#0 // destroy frame
+ ldp x19,x20,[x29,#16]
+ ldp x21,x22,[x29,#32]
+ ldp x29,x30,[sp],#96
+ AARCH64_VALIDATE_LINK_REGISTER
+ ret
+.size ecp_nistz256_point_double,.-ecp_nistz256_point_double
+___
+}
+
+########################################################################
+# void ecp_nistz256_point_add(P256_POINT *out,const P256_POINT *in1,
+# const P256_POINT *in2);
+{
+my ($res_x,$res_y,$res_z,
+ $H,$Hsqr,$R,$Rsqr,$Hcub,
+ $U1,$U2,$S1,$S2)=map(32*$_,(0..11));
+my ($Z1sqr, $Z2sqr) = ($Hsqr, $Rsqr);
+# above map() describes stack layout with 12 temporary
+# 256-bit vectors on top.
+my ($rp_real,$ap_real,$bp_real,$in1infty,$in2infty,$temp0,$temp1,$temp2)=map("x$_",(21..28));
+
+$code.=<<___;
+.globl ecp_nistz256_point_add
+.type ecp_nistz256_point_add,%function
+.align 5
+ecp_nistz256_point_add:
+ AARCH64_SIGN_LINK_REGISTER
+ stp x29,x30,[sp,#-96]!
+ add x29,sp,#0
+ stp x19,x20,[sp,#16]
+ stp x21,x22,[sp,#32]
+ stp x23,x24,[sp,#48]
+ stp x25,x26,[sp,#64]
+ stp x27,x28,[sp,#80]
+ sub sp,sp,#32*12
+
+ ldp $a0,$a1,[$bp,#64] // in2_z
+ ldp $a2,$a3,[$bp,#64+16]
+ mov $rp_real,$rp
+ mov $ap_real,$ap
+ mov $bp_real,$bp
+ adrp $poly3,:pg_hi21:.Lpoly
+ add $poly3,$poly3,:lo12:.Lpoly
+ ldr $poly1,[$poly3,#8]
+ ldr $poly3,[$poly3,#24]
+ orr $t0,$a0,$a1
+ orr $t2,$a2,$a3
+ orr $in2infty,$t0,$t2
+ cmp $in2infty,#0
+ csetm $in2infty,ne // ~in2infty
+ add $rp,sp,#$Z2sqr
+ bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Z2sqr, in2_z);
+
+ ldp $a0,$a1,[$ap_real,#64] // in1_z
+ ldp $a2,$a3,[$ap_real,#64+16]
+ orr $t0,$a0,$a1
+ orr $t2,$a2,$a3
+ orr $in1infty,$t0,$t2
+ cmp $in1infty,#0
+ csetm $in1infty,ne // ~in1infty
+ add $rp,sp,#$Z1sqr
+ bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Z1sqr, in1_z);
+
+ ldr $bi,[$bp_real,#64]
+ ldp $a0,$a1,[sp,#$Z2sqr]
+ ldp $a2,$a3,[sp,#$Z2sqr+16]
+ add $bp,$bp_real,#64
+ add $rp,sp,#$S1
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(S1, Z2sqr, in2_z);
+
+ ldr $bi,[$ap_real,#64]
+ ldp $a0,$a1,[sp,#$Z1sqr]
+ ldp $a2,$a3,[sp,#$Z1sqr+16]
+ add $bp,$ap_real,#64
+ add $rp,sp,#$S2
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, Z1sqr, in1_z);
+
+ ldr $bi,[$ap_real,#32]
+ ldp $a0,$a1,[sp,#$S1]
+ ldp $a2,$a3,[sp,#$S1+16]
+ add $bp,$ap_real,#32
+ add $rp,sp,#$S1
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(S1, S1, in1_y);
+
+ ldr $bi,[$bp_real,#32]
+ ldp $a0,$a1,[sp,#$S2]
+ ldp $a2,$a3,[sp,#$S2+16]
+ add $bp,$bp_real,#32
+ add $rp,sp,#$S2
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, S2, in2_y);
+
+ add $bp,sp,#$S1
+ ldr $bi,[sp,#$Z2sqr] // forward load for p256_mul_mont
+ ldp $a0,$a1,[$ap_real]
+ ldp $a2,$a3,[$ap_real,#16]
+ add $rp,sp,#$R
+ bl __ecp_nistz256_sub_from // p256_sub(R, S2, S1);
+
+ orr $acc0,$acc0,$acc1 // see if result is zero
+ orr $acc2,$acc2,$acc3
+ orr $temp0,$acc0,$acc2 // ~is_equal(S1,S2)
+
+ add $bp,sp,#$Z2sqr
+ add $rp,sp,#$U1
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(U1, in1_x, Z2sqr);
+
+ ldr $bi,[sp,#$Z1sqr]
+ ldp $a0,$a1,[$bp_real]
+ ldp $a2,$a3,[$bp_real,#16]
+ add $bp,sp,#$Z1sqr
+ add $rp,sp,#$U2
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(U2, in2_x, Z1sqr);
+
+ add $bp,sp,#$U1
+ ldp $a0,$a1,[sp,#$R] // forward load for p256_sqr_mont
+ ldp $a2,$a3,[sp,#$R+16]
+ add $rp,sp,#$H
+ bl __ecp_nistz256_sub_from // p256_sub(H, U2, U1);
+
+ orr $acc0,$acc0,$acc1 // see if result is zero
+ orr $acc2,$acc2,$acc3
+ orr $acc0,$acc0,$acc2 // ~is_equal(U1,U2)
+
+ mvn $temp1,$in1infty // -1/0 -> 0/-1
+ mvn $temp2,$in2infty // -1/0 -> 0/-1
+ orr $acc0,$acc0,$temp1
+ orr $acc0,$acc0,$temp2
+ orr $acc0,$acc0,$temp0
+ cbnz $acc0,.Ladd_proceed // if(~is_equal(U1,U2) | in1infty | in2infty | ~is_equal(S1,S2))
+
+.Ladd_double:
+ mov $ap,$ap_real
+ mov $rp,$rp_real
+ ldp x23,x24,[x29,#48]
+ ldp x25,x26,[x29,#64]
+ ldp x27,x28,[x29,#80]
+ add sp,sp,#256 // #256 is from #32*(12-4). difference in stack frames
+ b .Ldouble_shortcut
+
+.align 4
+.Ladd_proceed:
+ add $rp,sp,#$Rsqr
+ bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Rsqr, R);
+
+ ldr $bi,[$ap_real,#64]
+ ldp $a0,$a1,[sp,#$H]
+ ldp $a2,$a3,[sp,#$H+16]
+ add $bp,$ap_real,#64
+ add $rp,sp,#$res_z
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(res_z, H, in1_z);
+
+ ldp $a0,$a1,[sp,#$H]
+ ldp $a2,$a3,[sp,#$H+16]
+ add $rp,sp,#$Hsqr
+ bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Hsqr, H);
+
+ ldr $bi,[$bp_real,#64]
+ ldp $a0,$a1,[sp,#$res_z]
+ ldp $a2,$a3,[sp,#$res_z+16]
+ add $bp,$bp_real,#64
+ add $rp,sp,#$res_z
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(res_z, res_z, in2_z);
+
+ ldr $bi,[sp,#$H]
+ ldp $a0,$a1,[sp,#$Hsqr]
+ ldp $a2,$a3,[sp,#$Hsqr+16]
+ add $bp,sp,#$H
+ add $rp,sp,#$Hcub
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(Hcub, Hsqr, H);
+
+ ldr $bi,[sp,#$Hsqr]
+ ldp $a0,$a1,[sp,#$U1]
+ ldp $a2,$a3,[sp,#$U1+16]
+ add $bp,sp,#$Hsqr
+ add $rp,sp,#$U2
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(U2, U1, Hsqr);
+
+ mov $t0,$acc0
+ mov $t1,$acc1
+ mov $t2,$acc2
+ mov $t3,$acc3
+ add $rp,sp,#$Hsqr
+ bl __ecp_nistz256_add_to // p256_mul_by_2(Hsqr, U2);
+
+ add $bp,sp,#$Rsqr
+ add $rp,sp,#$res_x
+ bl __ecp_nistz256_sub_morf // p256_sub(res_x, Rsqr, Hsqr);
+
+ add $bp,sp,#$Hcub
+ bl __ecp_nistz256_sub_from // p256_sub(res_x, res_x, Hcub);
+
+ add $bp,sp,#$U2
+ ldr $bi,[sp,#$Hcub] // forward load for p256_mul_mont
+ ldp $a0,$a1,[sp,#$S1]
+ ldp $a2,$a3,[sp,#$S1+16]
+ add $rp,sp,#$res_y
+ bl __ecp_nistz256_sub_morf // p256_sub(res_y, U2, res_x);
+
+ add $bp,sp,#$Hcub
+ add $rp,sp,#$S2
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, S1, Hcub);
+
+ ldr $bi,[sp,#$R]
+ ldp $a0,$a1,[sp,#$res_y]
+ ldp $a2,$a3,[sp,#$res_y+16]
+ add $bp,sp,#$R
+ add $rp,sp,#$res_y
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(res_y, res_y, R);
+
+ add $bp,sp,#$S2
+ bl __ecp_nistz256_sub_from // p256_sub(res_y, res_y, S2);
+
+ ldp $a0,$a1,[sp,#$res_x] // res
+ ldp $a2,$a3,[sp,#$res_x+16]
+ ldp $t0,$t1,[$bp_real] // in2
+ ldp $t2,$t3,[$bp_real,#16]
+___
+for($i=0;$i<64;$i+=32) { # conditional moves
+$code.=<<___;
+ ldp $acc0,$acc1,[$ap_real,#$i] // in1
+ cmp $in1infty,#0 // ~$in1intfy, remember?
+ ldp $acc2,$acc3,[$ap_real,#$i+16]
+ csel $t0,$a0,$t0,ne
+ csel $t1,$a1,$t1,ne
+ ldp $a0,$a1,[sp,#$res_x+$i+32] // res
+ csel $t2,$a2,$t2,ne
+ csel $t3,$a3,$t3,ne
+ cmp $in2infty,#0 // ~$in2intfy, remember?
+ ldp $a2,$a3,[sp,#$res_x+$i+48]
+ csel $acc0,$t0,$acc0,ne
+ csel $acc1,$t1,$acc1,ne
+ ldp $t0,$t1,[$bp_real,#$i+32] // in2
+ csel $acc2,$t2,$acc2,ne
+ csel $acc3,$t3,$acc3,ne
+ ldp $t2,$t3,[$bp_real,#$i+48]
+ stp $acc0,$acc1,[$rp_real,#$i]
+ stp $acc2,$acc3,[$rp_real,#$i+16]
+___
+}
+$code.=<<___;
+ ldp $acc0,$acc1,[$ap_real,#$i] // in1
+ cmp $in1infty,#0 // ~$in1intfy, remember?
+ ldp $acc2,$acc3,[$ap_real,#$i+16]
+ csel $t0,$a0,$t0,ne
+ csel $t1,$a1,$t1,ne
+ csel $t2,$a2,$t2,ne
+ csel $t3,$a3,$t3,ne
+ cmp $in2infty,#0 // ~$in2intfy, remember?
+ csel $acc0,$t0,$acc0,ne
+ csel $acc1,$t1,$acc1,ne
+ csel $acc2,$t2,$acc2,ne
+ csel $acc3,$t3,$acc3,ne
+ stp $acc0,$acc1,[$rp_real,#$i]
+ stp $acc2,$acc3,[$rp_real,#$i+16]
+
+.Ladd_done:
+ add sp,x29,#0 // destroy frame
+ ldp x19,x20,[x29,#16]
+ ldp x21,x22,[x29,#32]
+ ldp x23,x24,[x29,#48]
+ ldp x25,x26,[x29,#64]
+ ldp x27,x28,[x29,#80]
+ ldp x29,x30,[sp],#96
+ AARCH64_VALIDATE_LINK_REGISTER
+ ret
+.size ecp_nistz256_point_add,.-ecp_nistz256_point_add
+___
+}
+
+########################################################################
+# void ecp_nistz256_point_add_affine(P256_POINT *out,const P256_POINT *in1,
+# const P256_POINT_AFFINE *in2);
+{
+my ($res_x,$res_y,$res_z,
+ $U2,$S2,$H,$R,$Hsqr,$Hcub,$Rsqr)=map(32*$_,(0..9));
+my $Z1sqr = $S2;
+# above map() describes stack layout with 10 temporary
+# 256-bit vectors on top.
+my ($rp_real,$ap_real,$bp_real,$in1infty,$in2infty,$temp)=map("x$_",(21..26));
+
+$code.=<<___;
+.globl ecp_nistz256_point_add_affine
+.type ecp_nistz256_point_add_affine,%function
+.align 5
+ecp_nistz256_point_add_affine:
+ AARCH64_SIGN_LINK_REGISTER
+ stp x29,x30,[sp,#-80]!
+ add x29,sp,#0
+ stp x19,x20,[sp,#16]
+ stp x21,x22,[sp,#32]
+ stp x23,x24,[sp,#48]
+ stp x25,x26,[sp,#64]
+ sub sp,sp,#32*10
+
+ mov $rp_real,$rp
+ mov $ap_real,$ap
+ mov $bp_real,$bp
+ adrp $poly3,:pg_hi21:.Lpoly
+ add $poly3,$poly3,:lo12:.Lpoly
+ ldr $poly1,[$poly3,#8]
+ ldr $poly3,[$poly3,#24]
+
+ ldp $a0,$a1,[$ap,#64] // in1_z
+ ldp $a2,$a3,[$ap,#64+16]
+ orr $t0,$a0,$a1
+ orr $t2,$a2,$a3
+ orr $in1infty,$t0,$t2
+ cmp $in1infty,#0
+ csetm $in1infty,ne // ~in1infty
+
+ ldp $acc0,$acc1,[$bp] // in2_x
+ ldp $acc2,$acc3,[$bp,#16]
+ ldp $t0,$t1,[$bp,#32] // in2_y
+ ldp $t2,$t3,[$bp,#48]
+ orr $acc0,$acc0,$acc1
+ orr $acc2,$acc2,$acc3
+ orr $t0,$t0,$t1
+ orr $t2,$t2,$t3
+ orr $acc0,$acc0,$acc2
+ orr $t0,$t0,$t2
+ orr $in2infty,$acc0,$t0
+ cmp $in2infty,#0
+ csetm $in2infty,ne // ~in2infty
+
+ add $rp,sp,#$Z1sqr
+ bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Z1sqr, in1_z);
+
+ mov $a0,$acc0
+ mov $a1,$acc1
+ mov $a2,$acc2
+ mov $a3,$acc3
+ ldr $bi,[$bp_real]
+ add $bp,$bp_real,#0
+ add $rp,sp,#$U2
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(U2, Z1sqr, in2_x);
+
+ add $bp,$ap_real,#0
+ ldr $bi,[$ap_real,#64] // forward load for p256_mul_mont
+ ldp $a0,$a1,[sp,#$Z1sqr]
+ ldp $a2,$a3,[sp,#$Z1sqr+16]
+ add $rp,sp,#$H
+ bl __ecp_nistz256_sub_from // p256_sub(H, U2, in1_x);
+
+ add $bp,$ap_real,#64
+ add $rp,sp,#$S2
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, Z1sqr, in1_z);
+
+ ldr $bi,[$ap_real,#64]
+ ldp $a0,$a1,[sp,#$H]
+ ldp $a2,$a3,[sp,#$H+16]
+ add $bp,$ap_real,#64
+ add $rp,sp,#$res_z
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(res_z, H, in1_z);
+
+ ldr $bi,[$bp_real,#32]
+ ldp $a0,$a1,[sp,#$S2]
+ ldp $a2,$a3,[sp,#$S2+16]
+ add $bp,$bp_real,#32
+ add $rp,sp,#$S2
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, S2, in2_y);
+
+ add $bp,$ap_real,#32
+ ldp $a0,$a1,[sp,#$H] // forward load for p256_sqr_mont
+ ldp $a2,$a3,[sp,#$H+16]
+ add $rp,sp,#$R
+ bl __ecp_nistz256_sub_from // p256_sub(R, S2, in1_y);
+
+ add $rp,sp,#$Hsqr
+ bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Hsqr, H);
+
+ ldp $a0,$a1,[sp,#$R]
+ ldp $a2,$a3,[sp,#$R+16]
+ add $rp,sp,#$Rsqr
+ bl __ecp_nistz256_sqr_mont // p256_sqr_mont(Rsqr, R);
+
+ ldr $bi,[sp,#$H]
+ ldp $a0,$a1,[sp,#$Hsqr]
+ ldp $a2,$a3,[sp,#$Hsqr+16]
+ add $bp,sp,#$H
+ add $rp,sp,#$Hcub
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(Hcub, Hsqr, H);
+
+ ldr $bi,[$ap_real]
+ ldp $a0,$a1,[sp,#$Hsqr]
+ ldp $a2,$a3,[sp,#$Hsqr+16]
+ add $bp,$ap_real,#0
+ add $rp,sp,#$U2
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(U2, in1_x, Hsqr);
+
+ mov $t0,$acc0
+ mov $t1,$acc1
+ mov $t2,$acc2
+ mov $t3,$acc3
+ add $rp,sp,#$Hsqr
+ bl __ecp_nistz256_add_to // p256_mul_by_2(Hsqr, U2);
+
+ add $bp,sp,#$Rsqr
+ add $rp,sp,#$res_x
+ bl __ecp_nistz256_sub_morf // p256_sub(res_x, Rsqr, Hsqr);
+
+ add $bp,sp,#$Hcub
+ bl __ecp_nistz256_sub_from // p256_sub(res_x, res_x, Hcub);
+
+ add $bp,sp,#$U2
+ ldr $bi,[$ap_real,#32] // forward load for p256_mul_mont
+ ldp $a0,$a1,[sp,#$Hcub]
+ ldp $a2,$a3,[sp,#$Hcub+16]
+ add $rp,sp,#$res_y
+ bl __ecp_nistz256_sub_morf // p256_sub(res_y, U2, res_x);
+
+ add $bp,$ap_real,#32
+ add $rp,sp,#$S2
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(S2, in1_y, Hcub);
+
+ ldr $bi,[sp,#$R]
+ ldp $a0,$a1,[sp,#$res_y]
+ ldp $a2,$a3,[sp,#$res_y+16]
+ add $bp,sp,#$R
+ add $rp,sp,#$res_y
+ bl __ecp_nistz256_mul_mont // p256_mul_mont(res_y, res_y, R);
+
+ add $bp,sp,#$S2
+ bl __ecp_nistz256_sub_from // p256_sub(res_y, res_y, S2);
+
+ ldp $a0,$a1,[sp,#$res_x] // res
+ ldp $a2,$a3,[sp,#$res_x+16]
+ ldp $t0,$t1,[$bp_real] // in2
+ ldp $t2,$t3,[$bp_real,#16]
+___
+for($i=0;$i<64;$i+=32) { # conditional moves
+$code.=<<___;
+ ldp $acc0,$acc1,[$ap_real,#$i] // in1
+ cmp $in1infty,#0 // ~$in1intfy, remember?
+ ldp $acc2,$acc3,[$ap_real,#$i+16]
+ csel $t0,$a0,$t0,ne
+ csel $t1,$a1,$t1,ne
+ ldp $a0,$a1,[sp,#$res_x+$i+32] // res
+ csel $t2,$a2,$t2,ne
+ csel $t3,$a3,$t3,ne
+ cmp $in2infty,#0 // ~$in2intfy, remember?
+ ldp $a2,$a3,[sp,#$res_x+$i+48]
+ csel $acc0,$t0,$acc0,ne
+ csel $acc1,$t1,$acc1,ne
+ ldp $t0,$t1,[$bp_real,#$i+32] // in2
+ csel $acc2,$t2,$acc2,ne
+ csel $acc3,$t3,$acc3,ne
+ ldp $t2,$t3,[$bp_real,#$i+48]
+ stp $acc0,$acc1,[$rp_real,#$i]
+ stp $acc2,$acc3,[$rp_real,#$i+16]
+___
+$code.=<<___ if ($i == 0);
+ adrp $bp_real,:pg_hi21:.Lone_mont-64
+ add $bp_real,$bp_real,:lo12:.Lone_mont-64
+___
+}
+$code.=<<___;
+ ldp $acc0,$acc1,[$ap_real,#$i] // in1
+ cmp $in1infty,#0 // ~$in1intfy, remember?
+ ldp $acc2,$acc3,[$ap_real,#$i+16]
+ csel $t0,$a0,$t0,ne
+ csel $t1,$a1,$t1,ne
+ csel $t2,$a2,$t2,ne
+ csel $t3,$a3,$t3,ne
+ cmp $in2infty,#0 // ~$in2intfy, remember?
+ csel $acc0,$t0,$acc0,ne
+ csel $acc1,$t1,$acc1,ne
+ csel $acc2,$t2,$acc2,ne
+ csel $acc3,$t3,$acc3,ne
+ stp $acc0,$acc1,[$rp_real,#$i]
+ stp $acc2,$acc3,[$rp_real,#$i+16]
+
+ add sp,x29,#0 // destroy frame
+ ldp x19,x20,[x29,#16]
+ ldp x21,x22,[x29,#32]
+ ldp x23,x24,[x29,#48]
+ ldp x25,x26,[x29,#64]
+ ldp x29,x30,[sp],#80
+ AARCH64_VALIDATE_LINK_REGISTER
+ ret
+.size ecp_nistz256_point_add_affine,.-ecp_nistz256_point_add_affine
+___
+}
+if (1) {
+my ($ord0,$ord1) = ($poly1,$poly3);
+my ($ord2,$ord3,$ordk,$t4) = map("x$_",(21..24));
+my $acc7 = $bi;
+
+$code.=<<___;
+////////////////////////////////////////////////////////////////////////
+// void ecp_nistz256_ord_mul_mont(uint64_t res[4], uint64_t a[4],
+// uint64_t b[4]);
+.globl ecp_nistz256_ord_mul_mont
+.type ecp_nistz256_ord_mul_mont,%function
+.align 4
+ecp_nistz256_ord_mul_mont:
+ AARCH64_VALID_CALL_TARGET
+ // Armv8.3-A PAuth: even though x30 is pushed to stack it is not popped later.
+ stp x29,x30,[sp,#-64]!
+ add x29,sp,#0
+ stp x19,x20,[sp,#16]
+ stp x21,x22,[sp,#32]
+ stp x23,x24,[sp,#48]
+
+ adrp $ordk,:pg_hi21:.Lord
+ add $ordk,$ordk,:lo12:.Lord
+ ldr $bi,[$bp] // bp[0]
+ ldp $a0,$a1,[$ap]
+ ldp $a2,$a3,[$ap,#16]
+
+ ldp $ord0,$ord1,[$ordk,#0]
+ ldp $ord2,$ord3,[$ordk,#16]
+ ldr $ordk,[$ordk,#32]
+
+ mul $acc0,$a0,$bi // a[0]*b[0]
+ umulh $t0,$a0,$bi
+
+ mul $acc1,$a1,$bi // a[1]*b[0]
+ umulh $t1,$a1,$bi
+
+ mul $acc2,$a2,$bi // a[2]*b[0]
+ umulh $t2,$a2,$bi
+
+ mul $acc3,$a3,$bi // a[3]*b[0]
+ umulh $acc4,$a3,$bi
+
+ mul $t4,$acc0,$ordk
+
+ adds $acc1,$acc1,$t0 // accumulate high parts of multiplication
+ adcs $acc2,$acc2,$t1
+ adcs $acc3,$acc3,$t2
+ adc $acc4,$acc4,xzr
+ mov $acc5,xzr
+___
+for ($i=1;$i<4;$i++) {
+ ################################################################
+ # ffff0000.ffffffff.yyyyyyyy.zzzzzzzz
+ # * abcdefgh
+ # + xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx
+ #
+ # Now observing that ff..ff*x = (2^n-1)*x = 2^n*x-x, we
+ # rewrite above as:
+ #
+ # xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx
+ # - 0000abcd.efgh0000.abcdefgh.00000000.00000000
+ # + abcdefgh.abcdefgh.yzayzbyz.cyzdyzey.zfyzgyzh
+$code.=<<___;
+ ldr $bi,[$bp,#8*$i] // b[i]
+
+ lsl $t0,$t4,#32
+ subs $acc2,$acc2,$t4
+ lsr $t1,$t4,#32
+ sbcs $acc3,$acc3,$t0
+ sbcs $acc4,$acc4,$t1
+ sbc $acc5,$acc5,xzr
+
+ subs xzr,$acc0,#1
+ umulh $t1,$ord0,$t4
+ mul $t2,$ord1,$t4
+ umulh $t3,$ord1,$t4
+
+ adcs $t2,$t2,$t1
+ mul $t0,$a0,$bi
+ adc $t3,$t3,xzr
+ mul $t1,$a1,$bi
+
+ adds $acc0,$acc1,$t2
+ mul $t2,$a2,$bi
+ adcs $acc1,$acc2,$t3
+ mul $t3,$a3,$bi
+ adcs $acc2,$acc3,$t4
+ adcs $acc3,$acc4,$t4
+ adc $acc4,$acc5,xzr
+
+ adds $acc0,$acc0,$t0 // accumulate low parts
+ umulh $t0,$a0,$bi
+ adcs $acc1,$acc1,$t1
+ umulh $t1,$a1,$bi
+ adcs $acc2,$acc2,$t2
+ umulh $t2,$a2,$bi
+ adcs $acc3,$acc3,$t3
+ umulh $t3,$a3,$bi
+ adc $acc4,$acc4,xzr
+ mul $t4,$acc0,$ordk
+ adds $acc1,$acc1,$t0 // accumulate high parts
+ adcs $acc2,$acc2,$t1
+ adcs $acc3,$acc3,$t2
+ adcs $acc4,$acc4,$t3
+ adc $acc5,xzr,xzr
+___
+}
+$code.=<<___;
+ lsl $t0,$t4,#32 // last reduction
+ subs $acc2,$acc2,$t4
+ lsr $t1,$t4,#32
+ sbcs $acc3,$acc3,$t0
+ sbcs $acc4,$acc4,$t1
+ sbc $acc5,$acc5,xzr
+
+ subs xzr,$acc0,#1
+ umulh $t1,$ord0,$t4
+ mul $t2,$ord1,$t4
+ umulh $t3,$ord1,$t4
+
+ adcs $t2,$t2,$t1
+ adc $t3,$t3,xzr
+
+ adds $acc0,$acc1,$t2
+ adcs $acc1,$acc2,$t3
+ adcs $acc2,$acc3,$t4
+ adcs $acc3,$acc4,$t4
+ adc $acc4,$acc5,xzr
+
+ subs $t0,$acc0,$ord0 // ret -= modulus
+ sbcs $t1,$acc1,$ord1
+ sbcs $t2,$acc2,$ord2
+ sbcs $t3,$acc3,$ord3
+ sbcs xzr,$acc4,xzr
+
+ csel $acc0,$acc0,$t0,lo // ret = borrow ? ret : ret-modulus
+ csel $acc1,$acc1,$t1,lo
+ csel $acc2,$acc2,$t2,lo
+ stp $acc0,$acc1,[$rp]
+ csel $acc3,$acc3,$t3,lo
+ stp $acc2,$acc3,[$rp,#16]
+
+ ldp x19,x20,[sp,#16]
+ ldp x21,x22,[sp,#32]
+ ldp x23,x24,[sp,#48]
+ ldr x29,[sp],#64
+ ret
+.size ecp_nistz256_ord_mul_mont,.-ecp_nistz256_ord_mul_mont
+
+////////////////////////////////////////////////////////////////////////
+// void ecp_nistz256_ord_sqr_mont(uint64_t res[4], uint64_t a[4],
+// uint64_t rep);
+.globl ecp_nistz256_ord_sqr_mont
+.type ecp_nistz256_ord_sqr_mont,%function
+.align 4
+ecp_nistz256_ord_sqr_mont:
+ AARCH64_VALID_CALL_TARGET
+ // Armv8.3-A PAuth: even though x30 is pushed to stack it is not popped later.
+ stp x29,x30,[sp,#-64]!
+ add x29,sp,#0
+ stp x19,x20,[sp,#16]
+ stp x21,x22,[sp,#32]
+ stp x23,x24,[sp,#48]
+
+ adrp $ordk,:pg_hi21:.Lord
+ add $ordk,$ordk,:lo12:.Lord
+ ldp $a0,$a1,[$ap]
+ ldp $a2,$a3,[$ap,#16]
+
+ ldp $ord0,$ord1,[$ordk,#0]
+ ldp $ord2,$ord3,[$ordk,#16]
+ ldr $ordk,[$ordk,#32]
+ b .Loop_ord_sqr
+
+.align 4
+.Loop_ord_sqr:
+ sub $bp,$bp,#1
+ ////////////////////////////////////////////////////////////////
+ // | | | | | |a1*a0| |
+ // | | | | |a2*a0| | |
+ // | |a3*a2|a3*a0| | | |
+ // | | | |a2*a1| | | |
+ // | | |a3*a1| | | | |
+ // *| | | | | | | | 2|
+ // +|a3*a3|a2*a2|a1*a1|a0*a0|
+ // |--+--+--+--+--+--+--+--|
+ // |A7|A6|A5|A4|A3|A2|A1|A0|, where Ax is $accx, i.e. follow $accx
+ //
+ // "can't overflow" below mark carrying into high part of
+ // multiplication result, which can't overflow, because it
+ // can never be all ones.
+
+ mul $acc1,$a1,$a0 // a[1]*a[0]
+ umulh $t1,$a1,$a0
+ mul $acc2,$a2,$a0 // a[2]*a[0]
+ umulh $t2,$a2,$a0
+ mul $acc3,$a3,$a0 // a[3]*a[0]
+ umulh $acc4,$a3,$a0
+
+ adds $acc2,$acc2,$t1 // accumulate high parts of multiplication
+ mul $t0,$a2,$a1 // a[2]*a[1]
+ umulh $t1,$a2,$a1
+ adcs $acc3,$acc3,$t2
+ mul $t2,$a3,$a1 // a[3]*a[1]
+ umulh $t3,$a3,$a1
+ adc $acc4,$acc4,xzr // can't overflow
+
+ mul $acc5,$a3,$a2 // a[3]*a[2]
+ umulh $acc6,$a3,$a2
+
+ adds $t1,$t1,$t2 // accumulate high parts of multiplication
+ mul $acc0,$a0,$a0 // a[0]*a[0]
+ adc $t2,$t3,xzr // can't overflow
+
+ adds $acc3,$acc3,$t0 // accumulate low parts of multiplication
+ umulh $a0,$a0,$a0
+ adcs $acc4,$acc4,$t1
+ mul $t1,$a1,$a1 // a[1]*a[1]
+ adcs $acc5,$acc5,$t2
+ umulh $a1,$a1,$a1
+ adc $acc6,$acc6,xzr // can't overflow
+
+ adds $acc1,$acc1,$acc1 // acc[1-6]*=2
+ mul $t2,$a2,$a2 // a[2]*a[2]
+ adcs $acc2,$acc2,$acc2
+ umulh $a2,$a2,$a2
+ adcs $acc3,$acc3,$acc3
+ mul $t3,$a3,$a3 // a[3]*a[3]
+ adcs $acc4,$acc4,$acc4
+ umulh $a3,$a3,$a3
+ adcs $acc5,$acc5,$acc5
+ adcs $acc6,$acc6,$acc6
+ adc $acc7,xzr,xzr
+
+ adds $acc1,$acc1,$a0 // +a[i]*a[i]
+ mul $t4,$acc0,$ordk
+ adcs $acc2,$acc2,$t1
+ adcs $acc3,$acc3,$a1
+ adcs $acc4,$acc4,$t2
+ adcs $acc5,$acc5,$a2
+ adcs $acc6,$acc6,$t3
+ adc $acc7,$acc7,$a3
+___
+for($i=0; $i<4; $i++) { # reductions
+$code.=<<___;
+ subs xzr,$acc0,#1
+ umulh $t1,$ord0,$t4
+ mul $t2,$ord1,$t4
+ umulh $t3,$ord1,$t4
+
+ adcs $t2,$t2,$t1
+ adc $t3,$t3,xzr
+
+ adds $acc0,$acc1,$t2
+ adcs $acc1,$acc2,$t3
+ adcs $acc2,$acc3,$t4
+ adc $acc3,xzr,$t4 // can't overflow
+___
+$code.=<<___ if ($i<3);
+ mul $t3,$acc0,$ordk
+___
+$code.=<<___;
+ lsl $t0,$t4,#32
+ subs $acc1,$acc1,$t4
+ lsr $t1,$t4,#32
+ sbcs $acc2,$acc2,$t0
+ sbc $acc3,$acc3,$t1 // can't borrow
+___
+ ($t3,$t4) = ($t4,$t3);
+}
+$code.=<<___;
+ adds $acc0,$acc0,$acc4 // accumulate upper half
+ adcs $acc1,$acc1,$acc5
+ adcs $acc2,$acc2,$acc6
+ adcs $acc3,$acc3,$acc7
+ adc $acc4,xzr,xzr
+
+ subs $t0,$acc0,$ord0 // ret -= modulus
+ sbcs $t1,$acc1,$ord1
+ sbcs $t2,$acc2,$ord2
+ sbcs $t3,$acc3,$ord3
+ sbcs xzr,$acc4,xzr
+
+ csel $a0,$acc0,$t0,lo // ret = borrow ? ret : ret-modulus
+ csel $a1,$acc1,$t1,lo
+ csel $a2,$acc2,$t2,lo
+ csel $a3,$acc3,$t3,lo
+
+ cbnz $bp,.Loop_ord_sqr
+
+ stp $a0,$a1,[$rp]
+ stp $a2,$a3,[$rp,#16]
+
+ ldp x19,x20,[sp,#16]
+ ldp x21,x22,[sp,#32]
+ ldp x23,x24,[sp,#48]
+ ldr x29,[sp],#64
+ ret
+.size ecp_nistz256_ord_sqr_mont,.-ecp_nistz256_ord_sqr_mont
+___
+} }
+
+########################################################################
+# select subroutines
+# These select functions are similar to those in p256-x86_64-asm.pl
+# They load all points in the lookup table
+# keeping in the output only the one corresponding to the input index.
+{
+my ($val,$in_t)=map("x$_",(0..1));
+my ($index)=("w2");
+my ($Idx_ctr,$Val_in, $Mask_64)=("w9", "x10", "x11");
+my ($Mask)=("v3");
+my ($Ra,$Rb,$Rc,$Rd,$Re,$Rf)=map("v$_",(16..21));
+my ($T0a,$T0b,$T0c,$T0d,$T0e,$T0f)=map("v$_",(22..27));
+$code.=<<___;
+////////////////////////////////////////////////////////////////////////
+// void ecp_nistz256_select_w5(uint64_t *val, uint64_t *in_t, int index);
+.globl ecp_nistz256_select_w5
+.type ecp_nistz256_select_w5,%function
+.align 4
+ecp_nistz256_select_w5:
+ AARCH64_VALID_CALL_TARGET
+
+ // $Val_in := $val
+ // $Idx_ctr := 0; loop counter and incremented internal index
+ mov $Val_in, $val
+ mov $Idx_ctr, #0
+
+ // [$Ra-$Rf] := 0
+ movi $Ra.16b, #0
+ movi $Rb.16b, #0
+ movi $Rc.16b, #0
+ movi $Rd.16b, #0
+ movi $Re.16b, #0
+ movi $Rf.16b, #0
+
+.Lselect_w5_loop:
+ // Loop 16 times.
+
+ // Increment index (loop counter); tested at the end of the loop
+ add $Idx_ctr, $Idx_ctr, #1
+
+ // [$T0a-$T0f] := Load a (3*256-bit = 6*128-bit) table entry starting at $in_t
+ // and advance $in_t to point to the next entry
+ ld1 {$T0a.2d, $T0b.2d, $T0c.2d, $T0d.2d}, [$in_t],#64
+
+ // $Mask_64 := ($Idx_ctr == $index)? All 1s : All 0s
+ cmp $Idx_ctr, $index
+ csetm $Mask_64, eq
+
+ // continue loading ...
+ ld1 {$T0e.2d, $T0f.2d}, [$in_t],#32
+
+ // duplicate mask_64 into Mask (all 0s or all 1s)
+ dup $Mask.2d, $Mask_64
+
+ // [$Ra-$Rd] := (Mask == all 1s)? [$T0a-$T0d] : [$Ra-$Rd]
+ // i.e., values in output registers will remain the same if $Idx_ctr != $index
+ bit $Ra.16b, $T0a.16b, $Mask.16b
+ bit $Rb.16b, $T0b.16b, $Mask.16b
+
+ bit $Rc.16b, $T0c.16b, $Mask.16b
+ bit $Rd.16b, $T0d.16b, $Mask.16b
+
+ bit $Re.16b, $T0e.16b, $Mask.16b
+ bit $Rf.16b, $T0f.16b, $Mask.16b
+
+ // If bit #4 is not 0 (i.e. idx_ctr < 16) loop back
+ tbz $Idx_ctr, #4, .Lselect_w5_loop
+
+ // Write [$Ra-$Rf] to memory at the output pointer
+ st1 {$Ra.2d, $Rb.2d, $Rc.2d, $Rd.2d}, [$Val_in],#64
+ st1 {$Re.2d, $Rf.2d}, [$Val_in]
+
+ ret
+.size ecp_nistz256_select_w5,.-ecp_nistz256_select_w5
+
+
+////////////////////////////////////////////////////////////////////////
+// void ecp_nistz256_select_w7(uint64_t *val, uint64_t *in_t, int index);
+.globl ecp_nistz256_select_w7
+.type ecp_nistz256_select_w7,%function
+.align 4
+ecp_nistz256_select_w7:
+ AARCH64_VALID_CALL_TARGET
+
+ // $Idx_ctr := 0; loop counter and incremented internal index
+ mov $Idx_ctr, #0
+
+ // [$Ra-$Rf] := 0
+ movi $Ra.16b, #0
+ movi $Rb.16b, #0
+ movi $Rc.16b, #0
+ movi $Rd.16b, #0
+
+.Lselect_w7_loop:
+ // Loop 64 times.
+
+ // Increment index (loop counter); tested at the end of the loop
+ add $Idx_ctr, $Idx_ctr, #1
+
+ // [$T0a-$T0d] := Load a (2*256-bit = 4*128-bit) table entry starting at $in_t
+ // and advance $in_t to point to the next entry
+ ld1 {$T0a.2d, $T0b.2d, $T0c.2d, $T0d.2d}, [$in_t],#64
+
+ // $Mask_64 := ($Idx_ctr == $index)? All 1s : All 0s
+ cmp $Idx_ctr, $index
+ csetm $Mask_64, eq
+
+ // duplicate mask_64 into Mask (all 0s or all 1s)
+ dup $Mask.2d, $Mask_64
+
+ // [$Ra-$Rd] := (Mask == all 1s)? [$T0a-$T0d] : [$Ra-$Rd]
+ // i.e., values in output registers will remain the same if $Idx_ctr != $index
+ bit $Ra.16b, $T0a.16b, $Mask.16b
+ bit $Rb.16b, $T0b.16b, $Mask.16b
+
+ bit $Rc.16b, $T0c.16b, $Mask.16b
+ bit $Rd.16b, $T0d.16b, $Mask.16b
+
+ // If bit #6 is not 0 (i.e. idx_ctr < 64) loop back
+ tbz $Idx_ctr, #6, .Lselect_w7_loop
+
+ // Write [$Ra-$Rd] to memory at the output pointer
+ st1 {$Ra.2d, $Rb.2d, $Rc.2d, $Rd.2d}, [$val]
+
+ ret
+.size ecp_nistz256_select_w7,.-ecp_nistz256_select_w7
+___
+}
+
+foreach (split("\n",$code)) {
+ s/\`([^\`]*)\`/eval $1/ge;
+
+ print $_,"\n";
+}
+close STDOUT or die "error closing STDOUT: $!"; # enforce flush
diff --git a/src/crypto/fipsmodule/ec/asm/p256-x86_64-asm.pl b/src/crypto/fipsmodule/ec/asm/p256-x86_64-asm.pl
new file mode 100755
index 0000000..0701996
--- /dev/null
+++ b/src/crypto/fipsmodule/ec/asm/p256-x86_64-asm.pl
@@ -0,0 +1,4158 @@
+#! /usr/bin/env perl
+# Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright (c) 2014, Intel Corporation. All Rights Reserved.
+# Copyright (c) 2015 CloudFlare, Inc.
+#
+# Licensed under the OpenSSL license (the "License"). You may not use
+# this file except in compliance with the License. You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+#
+# Originally written by Shay Gueron (1, 2), and Vlad Krasnov (1, 3)
+# (1) Intel Corporation, Israel Development Center, Haifa, Israel
+# (2) University of Haifa, Israel
+# (3) CloudFlare, Inc.
+#
+# Reference:
+# S.Gueron and V.Krasnov, "Fast Prime Field Elliptic Curve Cryptography with
+# 256 Bit Primes"
+
+# Further optimization by <appro@openssl.org>:
+#
+# this/original with/without -DECP_NISTZ256_ASM(*)
+# Opteron +15-49% +150-195%
+# Bulldozer +18-45% +175-240%
+# P4 +24-46% +100-150%
+# Westmere +18-34% +87-160%
+# Sandy Bridge +14-35% +120-185%
+# Ivy Bridge +11-35% +125-180%
+# Haswell +10-37% +160-200%
+# Broadwell +24-58% +210-270%
+# Atom +20-50% +180-240%
+# VIA Nano +50-160% +480-480%
+#
+# (*) "without -DECP_NISTZ256_ASM" refers to build with
+# "enable-ec_nistp_64_gcc_128";
+#
+# Ranges denote minimum and maximum improvement coefficients depending
+# on benchmark. In "this/original" column lower coefficient is for
+# ECDSA sign, while in "with/without" - for ECDH key agreement, and
+# higher - for ECDSA sign, relatively fastest server-side operation.
+# Keep in mind that +100% means 2x improvement.
+
+$flavour = shift;
+$output = shift;
+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
+
+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../../perlasm/x86_64-xlate.pl" and -f $xlate) or
+die "can't locate x86_64-xlate.pl";
+
+open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"";
+*STDOUT=*OUT;
+
+$avx = 2;
+$addx = 1;
+
+$code.=<<___;
+.text
+.extern OPENSSL_ia32cap_P
+
+# The polynomial
+.section .rodata
+.align 64
+.Lpoly:
+.quad 0xffffffffffffffff, 0x00000000ffffffff, 0x0000000000000000, 0xffffffff00000001
+
+.LOne:
+.long 1,1,1,1,1,1,1,1
+.LTwo:
+.long 2,2,2,2,2,2,2,2
+.LThree:
+.long 3,3,3,3,3,3,3,3
+.LONE_mont:
+.quad 0x0000000000000001, 0xffffffff00000000, 0xffffffffffffffff, 0x00000000fffffffe
+
+# Constants for computations modulo ord(p256)
+.Lord:
+.quad 0xf3b9cac2fc632551, 0xbce6faada7179e84, 0xffffffffffffffff, 0xffffffff00000000
+.LordK:
+.quad 0xccd1c8aaee00bc4f
+.text
+___
+
+{
+my ($a0,$a1,$a2,$a3)=map("%r$_",(8..11));
+my ($t0,$t1,$t2,$t3,$t4)=("%rax","%rdx","%rcx","%r12","%r13");
+my ($r_ptr,$a_ptr,$b_ptr)=("%rdi","%rsi","%rdx");
+
+$code.=<<___;
+
+################################################################################
+# void ecp_nistz256_neg(uint64_t res[4], uint64_t a[4]);
+.globl ecp_nistz256_neg
+.type ecp_nistz256_neg,\@function,2
+.align 32
+ecp_nistz256_neg:
+.cfi_startproc
+ push %r12
+.cfi_push %r12
+ push %r13
+.cfi_push %r13
+.Lneg_body:
+
+ xor $a0, $a0
+ xor $a1, $a1
+ xor $a2, $a2
+ xor $a3, $a3
+ xor $t4, $t4
+
+ sub 8*0($a_ptr), $a0
+ sbb 8*1($a_ptr), $a1
+ sbb 8*2($a_ptr), $a2
+ mov $a0, $t0
+ sbb 8*3($a_ptr), $a3
+ lea .Lpoly(%rip), $a_ptr
+ mov $a1, $t1
+ sbb \$0, $t4
+
+ add 8*0($a_ptr), $a0
+ mov $a2, $t2
+ adc 8*1($a_ptr), $a1
+ adc 8*2($a_ptr), $a2
+ mov $a3, $t3
+ adc 8*3($a_ptr), $a3
+ test $t4, $t4
+
+ cmovz $t0, $a0
+ cmovz $t1, $a1
+ mov $a0, 8*0($r_ptr)
+ cmovz $t2, $a2
+ mov $a1, 8*1($r_ptr)
+ cmovz $t3, $a3
+ mov $a2, 8*2($r_ptr)
+ mov $a3, 8*3($r_ptr)
+
+ mov 0(%rsp),%r13
+.cfi_restore %r13
+ mov 8(%rsp),%r12
+.cfi_restore %r12
+ lea 16(%rsp),%rsp
+.cfi_adjust_cfa_offset -16
+.Lneg_epilogue:
+ ret
+.cfi_endproc
+.size ecp_nistz256_neg,.-ecp_nistz256_neg
+___
+}
+{
+my ($r_ptr,$a_ptr,$b_org,$b_ptr)=("%rdi","%rsi","%rdx","%rbx");
+my ($acc0,$acc1,$acc2,$acc3,$acc4,$acc5,$acc6,$acc7)=map("%r$_",(8..15));
+my ($t0,$t1,$t2,$t3,$t4)=("%rcx","%rbp","%rbx","%rdx","%rax");
+my ($poly1,$poly3)=($acc6,$acc7);
+
+$code.=<<___;
+################################################################################
+# void ecp_nistz256_ord_mul_mont(
+# uint64_t res[4],
+# uint64_t a[4],
+# uint64_t b[4]);
+
+.globl ecp_nistz256_ord_mul_mont
+.type ecp_nistz256_ord_mul_mont,\@function,3
+.align 32
+ecp_nistz256_ord_mul_mont:
+.cfi_startproc
+___
+$code.=<<___ if ($addx);
+ leaq OPENSSL_ia32cap_P(%rip), %rcx
+ mov 8(%rcx), %rcx
+ and \$0x80100, %ecx
+ cmp \$0x80100, %ecx
+ je .Lecp_nistz256_ord_mul_montx
+___
+$code.=<<___;
+ push %rbp
+.cfi_push %rbp
+ push %rbx
+.cfi_push %rbx
+ push %r12
+.cfi_push %r12
+ push %r13
+.cfi_push %r13
+ push %r14
+.cfi_push %r14
+ push %r15
+.cfi_push %r15
+.Lord_mul_body:
+
+ mov 8*0($b_org), %rax
+ mov $b_org, $b_ptr
+ lea .Lord(%rip), %r14
+ mov .LordK(%rip), %r15
+
+ ################################# * b[0]
+ mov %rax, $t0
+ mulq 8*0($a_ptr)
+ mov %rax, $acc0
+ mov $t0, %rax
+ mov %rdx, $acc1
+
+ mulq 8*1($a_ptr)
+ add %rax, $acc1
+ mov $t0, %rax
+ adc \$0, %rdx
+ mov %rdx, $acc2
+
+ mulq 8*2($a_ptr)
+ add %rax, $acc2
+ mov $t0, %rax
+ adc \$0, %rdx
+
+ mov $acc0, $acc5
+ imulq %r15,$acc0
+
+ mov %rdx, $acc3
+ mulq 8*3($a_ptr)
+ add %rax, $acc3
+ mov $acc0, %rax
+ adc \$0, %rdx
+ mov %rdx, $acc4
+
+ ################################# First reduction step
+ mulq 8*0(%r14)
+ mov $acc0, $t1
+ add %rax, $acc5 # guaranteed to be zero
+ mov $acc0, %rax
+ adc \$0, %rdx
+ mov %rdx, $t0
+
+ sub $acc0, $acc2
+ sbb \$0, $acc0 # can't borrow
+
+ mulq 8*1(%r14)
+ add $t0, $acc1
+ adc \$0, %rdx
+ add %rax, $acc1
+ mov $t1, %rax
+ adc %rdx, $acc2
+ mov $t1, %rdx
+ adc \$0, $acc0 # can't overflow
+
+ shl \$32, %rax
+ shr \$32, %rdx
+ sub %rax, $acc3
+ mov 8*1($b_ptr), %rax
+ sbb %rdx, $t1 # can't borrow
+
+ add $acc0, $acc3
+ adc $t1, $acc4
+ adc \$0, $acc5
+
+ ################################# * b[1]
+ mov %rax, $t0
+ mulq 8*0($a_ptr)
+ add %rax, $acc1
+ mov $t0, %rax
+ adc \$0, %rdx
+ mov %rdx, $t1
+
+ mulq 8*1($a_ptr)
+ add $t1, $acc2
+ adc \$0, %rdx
+ add %rax, $acc2
+ mov $t0, %rax
+ adc \$0, %rdx
+ mov %rdx, $t1
+
+ mulq 8*2($a_ptr)
+ add $t1, $acc3
+ adc \$0, %rdx
+ add %rax, $acc3
+ mov $t0, %rax
+ adc \$0, %rdx
+
+ mov $acc1, $t0
+ imulq %r15, $acc1
+
+ mov %rdx, $t1
+ mulq 8*3($a_ptr)
+ add $t1, $acc4
+ adc \$0, %rdx
+ xor $acc0, $acc0
+ add %rax, $acc4
+ mov $acc1, %rax
+ adc %rdx, $acc5
+ adc \$0, $acc0
+
+ ################################# Second reduction step
+ mulq 8*0(%r14)
+ mov $acc1, $t1
+ add %rax, $t0 # guaranteed to be zero
+ mov $acc1, %rax
+ adc %rdx, $t0
+
+ sub $acc1, $acc3
+ sbb \$0, $acc1 # can't borrow
+
+ mulq 8*1(%r14)
+ add $t0, $acc2
+ adc \$0, %rdx
+ add %rax, $acc2
+ mov $t1, %rax
+ adc %rdx, $acc3
+ mov $t1, %rdx
+ adc \$0, $acc1 # can't overflow
+
+ shl \$32, %rax
+ shr \$32, %rdx
+ sub %rax, $acc4
+ mov 8*2($b_ptr), %rax
+ sbb %rdx, $t1 # can't borrow
+
+ add $acc1, $acc4
+ adc $t1, $acc5
+ adc \$0, $acc0
+
+ ################################## * b[2]
+ mov %rax, $t0
+ mulq 8*0($a_ptr)
+ add %rax, $acc2
+ mov $t0, %rax
+ adc \$0, %rdx
+ mov %rdx, $t1
+
+ mulq 8*1($a_ptr)
+ add $t1, $acc3
+ adc \$0, %rdx
+ add %rax, $acc3
+ mov $t0, %rax
+ adc \$0, %rdx
+ mov %rdx, $t1
+
+ mulq 8*2($a_ptr)
+ add $t1, $acc4
+ adc \$0, %rdx
+ add %rax, $acc4
+ mov $t0, %rax
+ adc \$0, %rdx
+
+ mov $acc2, $t0
+ imulq %r15, $acc2
+
+ mov %rdx, $t1
+ mulq 8*3($a_ptr)
+ add $t1, $acc5
+ adc \$0, %rdx
+ xor $acc1, $acc1
+ add %rax, $acc5
+ mov $acc2, %rax
+ adc %rdx, $acc0
+ adc \$0, $acc1
+
+ ################################# Third reduction step
+ mulq 8*0(%r14)
+ mov $acc2, $t1
+ add %rax, $t0 # guaranteed to be zero
+ mov $acc2, %rax
+ adc %rdx, $t0
+
+ sub $acc2, $acc4
+ sbb \$0, $acc2 # can't borrow
+
+ mulq 8*1(%r14)
+ add $t0, $acc3
+ adc \$0, %rdx
+ add %rax, $acc3
+ mov $t1, %rax
+ adc %rdx, $acc4
+ mov $t1, %rdx
+ adc \$0, $acc2 # can't overflow
+
+ shl \$32, %rax
+ shr \$32, %rdx
+ sub %rax, $acc5
+ mov 8*3($b_ptr), %rax
+ sbb %rdx, $t1 # can't borrow
+
+ add $acc2, $acc5
+ adc $t1, $acc0
+ adc \$0, $acc1
+
+ ################################# * b[3]
+ mov %rax, $t0
+ mulq 8*0($a_ptr)
+ add %rax, $acc3
+ mov $t0, %rax
+ adc \$0, %rdx
+ mov %rdx, $t1
+
+ mulq 8*1($a_ptr)
+ add $t1, $acc4
+ adc \$0, %rdx
+ add %rax, $acc4
+ mov $t0, %rax
+ adc \$0, %rdx
+ mov %rdx, $t1
+
+ mulq 8*2($a_ptr)
+ add $t1, $acc5
+ adc \$0, %rdx
+ add %rax, $acc5
+ mov $t0, %rax
+ adc \$0, %rdx
+
+ mov $acc3, $t0
+ imulq %r15, $acc3
+
+ mov %rdx, $t1
+ mulq 8*3($a_ptr)
+ add $t1, $acc0
+ adc \$0, %rdx
+ xor $acc2, $acc2
+ add %rax, $acc0
+ mov $acc3, %rax
+ adc %rdx, $acc1
+ adc \$0, $acc2
+
+ ################################# Last reduction step
+ mulq 8*0(%r14)
+ mov $acc3, $t1
+ add %rax, $t0 # guaranteed to be zero
+ mov $acc3, %rax
+ adc %rdx, $t0
+
+ sub $acc3, $acc5
+ sbb \$0, $acc3 # can't borrow
+
+ mulq 8*1(%r14)
+ add $t0, $acc4
+ adc \$0, %rdx
+ add %rax, $acc4
+ mov $t1, %rax
+ adc %rdx, $acc5
+ mov $t1, %rdx
+ adc \$0, $acc3 # can't overflow
+
+ shl \$32, %rax
+ shr \$32, %rdx
+ sub %rax, $acc0
+ sbb %rdx, $t1 # can't borrow
+
+ add $acc3, $acc0
+ adc $t1, $acc1
+ adc \$0, $acc2
+
+ ################################# Subtract ord
+ mov $acc4, $a_ptr
+ sub 8*0(%r14), $acc4
+ mov $acc5, $acc3
+ sbb 8*1(%r14), $acc5
+ mov $acc0, $t0
+ sbb 8*2(%r14), $acc0
+ mov $acc1, $t1
+ sbb 8*3(%r14), $acc1
+ sbb \$0, $acc2
+
+ cmovc $a_ptr, $acc4
+ cmovc $acc3, $acc5
+ cmovc $t0, $acc0
+ cmovc $t1, $acc1
+
+ mov $acc4, 8*0($r_ptr)
+ mov $acc5, 8*1($r_ptr)
+ mov $acc0, 8*2($r_ptr)
+ mov $acc1, 8*3($r_ptr)
+
+ mov 0(%rsp),%r15
+.cfi_restore %r15
+ mov 8(%rsp),%r14
+.cfi_restore %r14
+ mov 16(%rsp),%r13
+.cfi_restore %r13
+ mov 24(%rsp),%r12
+.cfi_restore %r12
+ mov 32(%rsp),%rbx
+.cfi_restore %rbx
+ mov 40(%rsp),%rbp
+.cfi_restore %rbp
+ lea 48(%rsp),%rsp
+.cfi_adjust_cfa_offset -48
+.Lord_mul_epilogue:
+ ret
+.cfi_endproc
+.size ecp_nistz256_ord_mul_mont,.-ecp_nistz256_ord_mul_mont
+
+################################################################################
+# void ecp_nistz256_ord_sqr_mont(
+# uint64_t res[4],
+# uint64_t a[4],
+# uint64_t rep);
+
+.globl ecp_nistz256_ord_sqr_mont
+.type ecp_nistz256_ord_sqr_mont,\@function,3
+.align 32
+ecp_nistz256_ord_sqr_mont:
+.cfi_startproc
+___
+$code.=<<___ if ($addx);
+ leaq OPENSSL_ia32cap_P(%rip), %rcx
+ mov 8(%rcx), %rcx
+ and \$0x80100, %ecx
+ cmp \$0x80100, %ecx
+ je .Lecp_nistz256_ord_sqr_montx
+___
+$code.=<<___;
+ push %rbp
+.cfi_push %rbp
+ push %rbx
+.cfi_push %rbx
+ push %r12
+.cfi_push %r12
+ push %r13
+.cfi_push %r13
+ push %r14
+.cfi_push %r14
+ push %r15
+.cfi_push %r15
+.Lord_sqr_body:
+
+ mov 8*0($a_ptr), $acc0
+ mov 8*1($a_ptr), %rax
+ mov 8*2($a_ptr), $acc6
+ mov 8*3($a_ptr), $acc7
+ lea .Lord(%rip), $a_ptr # pointer to modulus
+ mov $b_org, $b_ptr
+ jmp .Loop_ord_sqr
+
+.align 32
+.Loop_ord_sqr:
+ ################################# a[1:] * a[0]
+ mov %rax, $t1 # put aside a[1]
+ mul $acc0 # a[1] * a[0]
+ mov %rax, $acc1
+ movq $t1, %xmm1 # offload a[1]
+ mov $acc6, %rax
+ mov %rdx, $acc2
+
+ mul $acc0 # a[2] * a[0]
+ add %rax, $acc2
+ mov $acc7, %rax
+ movq $acc6, %xmm2 # offload a[2]
+ adc \$0, %rdx
+ mov %rdx, $acc3
+
+ mul $acc0 # a[3] * a[0]
+ add %rax, $acc3
+ mov $acc7, %rax
+ movq $acc7, %xmm3 # offload a[3]
+ adc \$0, %rdx
+ mov %rdx, $acc4
+
+ ################################# a[3] * a[2]
+ mul $acc6 # a[3] * a[2]
+ mov %rax, $acc5
+ mov $acc6, %rax
+ mov %rdx, $acc6
+
+ ################################# a[2:] * a[1]
+ mul $t1 # a[2] * a[1]
+ add %rax, $acc3
+ mov $acc7, %rax
+ adc \$0, %rdx
+ mov %rdx, $acc7
+
+ mul $t1 # a[3] * a[1]
+ add %rax, $acc4
+ adc \$0, %rdx
+
+ add $acc7, $acc4
+ adc %rdx, $acc5
+ adc \$0, $acc6 # can't overflow
+
+ ################################# *2
+ xor $acc7, $acc7
+ mov $acc0, %rax
+ add $acc1, $acc1
+ adc $acc2, $acc2
+ adc $acc3, $acc3
+ adc $acc4, $acc4
+ adc $acc5, $acc5
+ adc $acc6, $acc6
+ adc \$0, $acc7
+
+ ################################# Missing products
+ mul %rax # a[0] * a[0]
+ mov %rax, $acc0
+ movq %xmm1, %rax
+ mov %rdx, $t1
+
+ mul %rax # a[1] * a[1]
+ add $t1, $acc1
+ adc %rax, $acc2
+ movq %xmm2, %rax
+ adc \$0, %rdx
+ mov %rdx, $t1
+
+ mul %rax # a[2] * a[2]
+ add $t1, $acc3
+ adc %rax, $acc4
+ movq %xmm3, %rax
+ adc \$0, %rdx
+ mov %rdx, $t1
+
+ mov $acc0, $t0
+ imulq 8*4($a_ptr), $acc0 # *= .LordK
+
+ mul %rax # a[3] * a[3]
+ add $t1, $acc5
+ adc %rax, $acc6
+ mov 8*0($a_ptr), %rax # modulus[0]
+ adc %rdx, $acc7 # can't overflow
+
+ ################################# First reduction step
+ mul $acc0
+ mov $acc0, $t1
+ add %rax, $t0 # guaranteed to be zero
+ mov 8*1($a_ptr), %rax # modulus[1]
+ adc %rdx, $t0
+
+ sub $acc0, $acc2
+ sbb \$0, $t1 # can't borrow
+
+ mul $acc0
+ add $t0, $acc1
+ adc \$0, %rdx
+ add %rax, $acc1
+ mov $acc0, %rax
+ adc %rdx, $acc2
+ mov $acc0, %rdx
+ adc \$0, $t1 # can't overflow
+
+ mov $acc1, $t0
+ imulq 8*4($a_ptr), $acc1 # *= .LordK
+
+ shl \$32, %rax
+ shr \$32, %rdx
+ sub %rax, $acc3
+ mov 8*0($a_ptr), %rax
+ sbb %rdx, $acc0 # can't borrow
+
+ add $t1, $acc3
+ adc \$0, $acc0 # can't overflow
+
+ ################################# Second reduction step
+ mul $acc1
+ mov $acc1, $t1
+ add %rax, $t0 # guaranteed to be zero
+ mov 8*1($a_ptr), %rax
+ adc %rdx, $t0
+
+ sub $acc1, $acc3
+ sbb \$0, $t1 # can't borrow
+
+ mul $acc1
+ add $t0, $acc2
+ adc \$0, %rdx
+ add %rax, $acc2
+ mov $acc1, %rax
+ adc %rdx, $acc3
+ mov $acc1, %rdx
+ adc \$0, $t1 # can't overflow
+
+ mov $acc2, $t0
+ imulq 8*4($a_ptr), $acc2 # *= .LordK
+
+ shl \$32, %rax
+ shr \$32, %rdx
+ sub %rax, $acc0
+ mov 8*0($a_ptr), %rax
+ sbb %rdx, $acc1 # can't borrow
+
+ add $t1, $acc0
+ adc \$0, $acc1 # can't overflow
+
+ ################################# Third reduction step
+ mul $acc2
+ mov $acc2, $t1
+ add %rax, $t0 # guaranteed to be zero
+ mov 8*1($a_ptr), %rax
+ adc %rdx, $t0
+
+ sub $acc2, $acc0
+ sbb \$0, $t1 # can't borrow
+
+ mul $acc2
+ add $t0, $acc3
+ adc \$0, %rdx
+ add %rax, $acc3
+ mov $acc2, %rax
+ adc %rdx, $acc0
+ mov $acc2, %rdx
+ adc \$0, $t1 # can't overflow
+
+ mov $acc3, $t0
+ imulq 8*4($a_ptr), $acc3 # *= .LordK
+
+ shl \$32, %rax
+ shr \$32, %rdx
+ sub %rax, $acc1
+ mov 8*0($a_ptr), %rax
+ sbb %rdx, $acc2 # can't borrow
+
+ add $t1, $acc1
+ adc \$0, $acc2 # can't overflow
+
+ ################################# Last reduction step
+ mul $acc3
+ mov $acc3, $t1
+ add %rax, $t0 # guaranteed to be zero
+ mov 8*1($a_ptr), %rax
+ adc %rdx, $t0
+
+ sub $acc3, $acc1
+ sbb \$0, $t1 # can't borrow
+
+ mul $acc3
+ add $t0, $acc0
+ adc \$0, %rdx
+ add %rax, $acc0
+ mov $acc3, %rax
+ adc %rdx, $acc1
+ mov $acc3, %rdx
+ adc \$0, $t1 # can't overflow
+
+ shl \$32, %rax
+ shr \$32, %rdx
+ sub %rax, $acc2
+ sbb %rdx, $acc3 # can't borrow
+
+ add $t1, $acc2
+ adc \$0, $acc3 # can't overflow
+
+ ################################# Add bits [511:256] of the sqr result
+ xor %rdx, %rdx
+ add $acc4, $acc0
+ adc $acc5, $acc1
+ mov $acc0, $acc4
+ adc $acc6, $acc2
+ adc $acc7, $acc3
+ mov $acc1, %rax
+ adc \$0, %rdx
+
+ ################################# Compare to modulus
+ sub 8*0($a_ptr), $acc0
+ mov $acc2, $acc6
+ sbb 8*1($a_ptr), $acc1
+ sbb 8*2($a_ptr), $acc2
+ mov $acc3, $acc7
+ sbb 8*3($a_ptr), $acc3
+ sbb \$0, %rdx
+
+ cmovc $acc4, $acc0
+ cmovnc $acc1, %rax
+ cmovnc $acc2, $acc6
+ cmovnc $acc3, $acc7
+
+ dec $b_ptr
+ jnz .Loop_ord_sqr
+
+ mov $acc0, 8*0($r_ptr)
+ mov %rax, 8*1($r_ptr)
+ pxor %xmm1, %xmm1
+ mov $acc6, 8*2($r_ptr)
+ pxor %xmm2, %xmm2
+ mov $acc7, 8*3($r_ptr)
+ pxor %xmm3, %xmm3
+
+ mov 0(%rsp),%r15
+.cfi_restore %r15
+ mov 8(%rsp),%r14
+.cfi_restore %r14
+ mov 16(%rsp),%r13
+.cfi_restore %r13
+ mov 24(%rsp),%r12
+.cfi_restore %r12
+ mov 32(%rsp),%rbx
+.cfi_restore %rbx
+ mov 40(%rsp),%rbp
+.cfi_restore %rbp
+ lea 48(%rsp),%rsp
+.cfi_adjust_cfa_offset -48
+.Lord_sqr_epilogue:
+ ret
+.cfi_endproc
+.size ecp_nistz256_ord_sqr_mont,.-ecp_nistz256_ord_sqr_mont
+___
+
+$code.=<<___ if ($addx);
+################################################################################
+.type ecp_nistz256_ord_mul_montx,\@function,3
+.align 32
+ecp_nistz256_ord_mul_montx:
+.cfi_startproc
+.Lecp_nistz256_ord_mul_montx:
+ push %rbp
+.cfi_push %rbp
+ push %rbx
+.cfi_push %rbx
+ push %r12
+.cfi_push %r12
+ push %r13
+.cfi_push %r13
+ push %r14
+.cfi_push %r14
+ push %r15
+.cfi_push %r15
+.Lord_mulx_body:
+
+ mov $b_org, $b_ptr
+ mov 8*0($b_org), %rdx
+ mov 8*0($a_ptr), $acc1
+ mov 8*1($a_ptr), $acc2
+ mov 8*2($a_ptr), $acc3
+ mov 8*3($a_ptr), $acc4
+ lea -128($a_ptr), $a_ptr # control u-op density
+ lea .Lord-128(%rip), %r14
+ mov .LordK(%rip), %r15
+
+ ################################# Multiply by b[0]
+ mulx $acc1, $acc0, $acc1
+ mulx $acc2, $t0, $acc2
+ mulx $acc3, $t1, $acc3
+ add $t0, $acc1
+ mulx $acc4, $t0, $acc4
+ mov $acc0, %rdx
+ mulx %r15, %rdx, %rax
+ adc $t1, $acc2
+ adc $t0, $acc3
+ adc \$0, $acc4
+
+ ################################# reduction
+ xor $acc5, $acc5 # $acc5=0, cf=0, of=0
+ mulx 8*0+128(%r14), $t0, $t1
+ adcx $t0, $acc0 # guaranteed to be zero
+ adox $t1, $acc1
+
+ mulx 8*1+128(%r14), $t0, $t1
+ adcx $t0, $acc1
+ adox $t1, $acc2
+
+ mulx 8*2+128(%r14), $t0, $t1
+ adcx $t0, $acc2
+ adox $t1, $acc3
+
+ mulx 8*3+128(%r14), $t0, $t1
+ mov 8*1($b_ptr), %rdx
+ adcx $t0, $acc3
+ adox $t1, $acc4
+ adcx $acc0, $acc4
+ adox $acc0, $acc5
+ adc \$0, $acc5 # cf=0, of=0
+
+ ################################# Multiply by b[1]
+ mulx 8*0+128($a_ptr), $t0, $t1
+ adcx $t0, $acc1
+ adox $t1, $acc2
+
+ mulx 8*1+128($a_ptr), $t0, $t1
+ adcx $t0, $acc2
+ adox $t1, $acc3
+
+ mulx 8*2+128($a_ptr), $t0, $t1
+ adcx $t0, $acc3
+ adox $t1, $acc4
+
+ mulx 8*3+128($a_ptr), $t0, $t1
+ mov $acc1, %rdx
+ mulx %r15, %rdx, %rax
+ adcx $t0, $acc4
+ adox $t1, $acc5
+
+ adcx $acc0, $acc5
+ adox $acc0, $acc0
+ adc \$0, $acc0 # cf=0, of=0
+
+ ################################# reduction
+ mulx 8*0+128(%r14), $t0, $t1
+ adcx $t0, $acc1 # guaranteed to be zero
+ adox $t1, $acc2
+
+ mulx 8*1+128(%r14), $t0, $t1
+ adcx $t0, $acc2
+ adox $t1, $acc3
+
+ mulx 8*2+128(%r14), $t0, $t1
+ adcx $t0, $acc3
+ adox $t1, $acc4
+
+ mulx 8*3+128(%r14), $t0, $t1
+ mov 8*2($b_ptr), %rdx
+ adcx $t0, $acc4
+ adox $t1, $acc5
+ adcx $acc1, $acc5
+ adox $acc1, $acc0
+ adc \$0, $acc0 # cf=0, of=0
+
+ ################################# Multiply by b[2]
+ mulx 8*0+128($a_ptr), $t0, $t1
+ adcx $t0, $acc2
+ adox $t1, $acc3
+
+ mulx 8*1+128($a_ptr), $t0, $t1
+ adcx $t0, $acc3
+ adox $t1, $acc4
+
+ mulx 8*2+128($a_ptr), $t0, $t1
+ adcx $t0, $acc4
+ adox $t1, $acc5
+
+ mulx 8*3+128($a_ptr), $t0, $t1
+ mov $acc2, %rdx
+ mulx %r15, %rdx, %rax
+ adcx $t0, $acc5
+ adox $t1, $acc0
+
+ adcx $acc1, $acc0
+ adox $acc1, $acc1
+ adc \$0, $acc1 # cf=0, of=0
+
+ ################################# reduction
+ mulx 8*0+128(%r14), $t0, $t1
+ adcx $t0, $acc2 # guaranteed to be zero
+ adox $t1, $acc3
+
+ mulx 8*1+128(%r14), $t0, $t1
+ adcx $t0, $acc3
+ adox $t1, $acc4
+
+ mulx 8*2+128(%r14), $t0, $t1
+ adcx $t0, $acc4
+ adox $t1, $acc5
+
+ mulx 8*3+128(%r14), $t0, $t1
+ mov 8*3($b_ptr), %rdx
+ adcx $t0, $acc5
+ adox $t1, $acc0
+ adcx $acc2, $acc0
+ adox $acc2, $acc1
+ adc \$0, $acc1 # cf=0, of=0
+
+ ################################# Multiply by b[3]
+ mulx 8*0+128($a_ptr), $t0, $t1
+ adcx $t0, $acc3
+ adox $t1, $acc4
+
+ mulx 8*1+128($a_ptr), $t0, $t1
+ adcx $t0, $acc4
+ adox $t1, $acc5
+
+ mulx 8*2+128($a_ptr), $t0, $t1
+ adcx $t0, $acc5
+ adox $t1, $acc0
+
+ mulx 8*3+128($a_ptr), $t0, $t1
+ mov $acc3, %rdx
+ mulx %r15, %rdx, %rax
+ adcx $t0, $acc0
+ adox $t1, $acc1
+
+ adcx $acc2, $acc1
+ adox $acc2, $acc2
+ adc \$0, $acc2 # cf=0, of=0
+
+ ################################# reduction
+ mulx 8*0+128(%r14), $t0, $t1
+ adcx $t0, $acc3 # guranteed to be zero
+ adox $t1, $acc4
+
+ mulx 8*1+128(%r14), $t0, $t1
+ adcx $t0, $acc4
+ adox $t1, $acc5
+
+ mulx 8*2+128(%r14), $t0, $t1
+ adcx $t0, $acc5
+ adox $t1, $acc0
+
+ mulx 8*3+128(%r14), $t0, $t1
+ lea 128(%r14),%r14
+ mov $acc4, $t2
+ adcx $t0, $acc0
+ adox $t1, $acc1
+ mov $acc5, $t3
+ adcx $acc3, $acc1
+ adox $acc3, $acc2
+ adc \$0, $acc2
+
+ #################################
+ # Branch-less conditional subtraction of P
+ mov $acc0, $t0
+ sub 8*0(%r14), $acc4
+ sbb 8*1(%r14), $acc5
+ sbb 8*2(%r14), $acc0
+ mov $acc1, $t1
+ sbb 8*3(%r14), $acc1
+ sbb \$0, $acc2
+
+ cmovc $t2, $acc4
+ cmovc $t3, $acc5
+ cmovc $t0, $acc0
+ cmovc $t1, $acc1
+
+ mov $acc4, 8*0($r_ptr)
+ mov $acc5, 8*1($r_ptr)
+ mov $acc0, 8*2($r_ptr)
+ mov $acc1, 8*3($r_ptr)
+
+ mov 0(%rsp),%r15
+.cfi_restore %r15
+ mov 8(%rsp),%r14
+.cfi_restore %r14
+ mov 16(%rsp),%r13
+.cfi_restore %r13
+ mov 24(%rsp),%r12
+.cfi_restore %r12
+ mov 32(%rsp),%rbx
+.cfi_restore %rbx
+ mov 40(%rsp),%rbp
+.cfi_restore %rbp
+ lea 48(%rsp),%rsp
+.cfi_adjust_cfa_offset -48
+.Lord_mulx_epilogue:
+ ret
+.cfi_endproc
+.size ecp_nistz256_ord_mul_montx,.-ecp_nistz256_ord_mul_montx
+
+.type ecp_nistz256_ord_sqr_montx,\@function,3
+.align 32
+ecp_nistz256_ord_sqr_montx:
+.cfi_startproc
+.Lecp_nistz256_ord_sqr_montx:
+ push %rbp
+.cfi_push %rbp
+ push %rbx
+.cfi_push %rbx
+ push %r12
+.cfi_push %r12
+ push %r13
+.cfi_push %r13
+ push %r14
+.cfi_push %r14
+ push %r15
+.cfi_push %r15
+.Lord_sqrx_body:
+
+ mov $b_org, $b_ptr
+ mov 8*0($a_ptr), %rdx
+ mov 8*1($a_ptr), $acc6
+ mov 8*2($a_ptr), $acc7
+ mov 8*3($a_ptr), $acc0
+ lea .Lord(%rip), $a_ptr
+ jmp .Loop_ord_sqrx
+
+.align 32
+.Loop_ord_sqrx:
+ mulx $acc6, $acc1, $acc2 # a[0]*a[1]
+ mulx $acc7, $t0, $acc3 # a[0]*a[2]
+ mov %rdx, %rax # offload a[0]
+ movq $acc6, %xmm1 # offload a[1]
+ mulx $acc0, $t1, $acc4 # a[0]*a[3]
+ mov $acc6, %rdx
+ add $t0, $acc2
+ movq $acc7, %xmm2 # offload a[2]
+ adc $t1, $acc3
+ adc \$0, $acc4
+ xor $acc5, $acc5 # $acc5=0,cf=0,of=0
+ #################################
+ mulx $acc7, $t0, $t1 # a[1]*a[2]
+ adcx $t0, $acc3
+ adox $t1, $acc4
+
+ mulx $acc0, $t0, $t1 # a[1]*a[3]
+ mov $acc7, %rdx
+ adcx $t0, $acc4
+ adox $t1, $acc5
+ adc \$0, $acc5
+ #################################
+ mulx $acc0, $t0, $acc6 # a[2]*a[3]
+ mov %rax, %rdx
+ movq $acc0, %xmm3 # offload a[3]
+ xor $acc7, $acc7 # $acc7=0,cf=0,of=0
+ adcx $acc1, $acc1 # acc1:6<<1
+ adox $t0, $acc5
+ adcx $acc2, $acc2
+ adox $acc7, $acc6 # of=0
+
+ ################################# a[i]*a[i]
+ mulx %rdx, $acc0, $t1
+ movq %xmm1, %rdx
+ adcx $acc3, $acc3
+ adox $t1, $acc1
+ adcx $acc4, $acc4
+ mulx %rdx, $t0, $t4
+ movq %xmm2, %rdx
+ adcx $acc5, $acc5
+ adox $t0, $acc2
+ adcx $acc6, $acc6
+ mulx %rdx, $t0, $t1
+ .byte 0x67
+ movq %xmm3, %rdx
+ adox $t4, $acc3
+ adcx $acc7, $acc7
+ adox $t0, $acc4
+ adox $t1, $acc5
+ mulx %rdx, $t0, $t4
+ adox $t0, $acc6
+ adox $t4, $acc7
+
+ ################################# reduction
+ mov $acc0, %rdx
+ mulx 8*4($a_ptr), %rdx, $t0
+
+ xor %rax, %rax # cf=0, of=0
+ mulx 8*0($a_ptr), $t0, $t1
+ adcx $t0, $acc0 # guaranteed to be zero
+ adox $t1, $acc1
+ mulx 8*1($a_ptr), $t0, $t1
+ adcx $t0, $acc1
+ adox $t1, $acc2
+ mulx 8*2($a_ptr), $t0, $t1
+ adcx $t0, $acc2
+ adox $t1, $acc3
+ mulx 8*3($a_ptr), $t0, $t1
+ adcx $t0, $acc3
+ adox $t1, $acc0 # of=0
+ adcx %rax, $acc0 # cf=0
+
+ #################################
+ mov $acc1, %rdx
+ mulx 8*4($a_ptr), %rdx, $t0
+
+ mulx 8*0($a_ptr), $t0, $t1
+ adox $t0, $acc1 # guaranteed to be zero
+ adcx $t1, $acc2
+ mulx 8*1($a_ptr), $t0, $t1
+ adox $t0, $acc2
+ adcx $t1, $acc3
+ mulx 8*2($a_ptr), $t0, $t1
+ adox $t0, $acc3
+ adcx $t1, $acc0
+ mulx 8*3($a_ptr), $t0, $t1
+ adox $t0, $acc0
+ adcx $t1, $acc1 # cf=0
+ adox %rax, $acc1 # of=0
+
+ #################################
+ mov $acc2, %rdx
+ mulx 8*4($a_ptr), %rdx, $t0
+
+ mulx 8*0($a_ptr), $t0, $t1
+ adcx $t0, $acc2 # guaranteed to be zero
+ adox $t1, $acc3
+ mulx 8*1($a_ptr), $t0, $t1
+ adcx $t0, $acc3
+ adox $t1, $acc0
+ mulx 8*2($a_ptr), $t0, $t1
+ adcx $t0, $acc0
+ adox $t1, $acc1
+ mulx 8*3($a_ptr), $t0, $t1
+ adcx $t0, $acc1
+ adox $t1, $acc2 # of=0
+ adcx %rax, $acc2 # cf=0
+
+ #################################
+ mov $acc3, %rdx
+ mulx 8*4($a_ptr), %rdx, $t0
+
+ mulx 8*0($a_ptr), $t0, $t1
+ adox $t0, $acc3 # guaranteed to be zero
+ adcx $t1, $acc0
+ mulx 8*1($a_ptr), $t0, $t1
+ adox $t0, $acc0
+ adcx $t1, $acc1
+ mulx 8*2($a_ptr), $t0, $t1
+ adox $t0, $acc1
+ adcx $t1, $acc2
+ mulx 8*3($a_ptr), $t0, $t1
+ adox $t0, $acc2
+ adcx $t1, $acc3
+ adox %rax, $acc3
+
+ ################################# accumulate upper half
+ add $acc0, $acc4 # add $acc4, $acc0
+ adc $acc5, $acc1
+ mov $acc4, %rdx
+ adc $acc6, $acc2
+ adc $acc7, $acc3
+ mov $acc1, $acc6
+ adc \$0, %rax
+
+ ################################# compare to modulus
+ sub 8*0($a_ptr), $acc4
+ mov $acc2, $acc7
+ sbb 8*1($a_ptr), $acc1
+ sbb 8*2($a_ptr), $acc2
+ mov $acc3, $acc0
+ sbb 8*3($a_ptr), $acc3
+ sbb \$0, %rax
+
+ cmovnc $acc4, %rdx
+ cmovnc $acc1, $acc6
+ cmovnc $acc2, $acc7
+ cmovnc $acc3, $acc0
+
+ dec $b_ptr
+ jnz .Loop_ord_sqrx
+
+ mov %rdx, 8*0($r_ptr)
+ mov $acc6, 8*1($r_ptr)
+ pxor %xmm1, %xmm1
+ mov $acc7, 8*2($r_ptr)
+ pxor %xmm2, %xmm2
+ mov $acc0, 8*3($r_ptr)
+ pxor %xmm3, %xmm3
+
+ mov 0(%rsp),%r15
+.cfi_restore %r15
+ mov 8(%rsp),%r14
+.cfi_restore %r14
+ mov 16(%rsp),%r13
+.cfi_restore %r13
+ mov 24(%rsp),%r12
+.cfi_restore %r12
+ mov 32(%rsp),%rbx
+.cfi_restore %rbx
+ mov 40(%rsp),%rbp
+.cfi_restore %rbp
+ lea 48(%rsp),%rsp
+.cfi_adjust_cfa_offset -48
+.Lord_sqrx_epilogue:
+ ret
+.cfi_endproc
+.size ecp_nistz256_ord_sqr_montx,.-ecp_nistz256_ord_sqr_montx
+___
+
+$code.=<<___;
+################################################################################
+# void ecp_nistz256_mul_mont(
+# uint64_t res[4],
+# uint64_t a[4],
+# uint64_t b[4]);
+
+.globl ecp_nistz256_mul_mont
+.type ecp_nistz256_mul_mont,\@function,3
+.align 32
+ecp_nistz256_mul_mont:
+.cfi_startproc
+___
+$code.=<<___ if ($addx);
+ leaq OPENSSL_ia32cap_P(%rip), %rcx
+ mov 8(%rcx), %rcx
+ and \$0x80100, %ecx
+___
+$code.=<<___;
+.Lmul_mont:
+ push %rbp
+.cfi_push %rbp
+ push %rbx
+.cfi_push %rbx
+ push %r12
+.cfi_push %r12
+ push %r13
+.cfi_push %r13
+ push %r14
+.cfi_push %r14
+ push %r15
+.cfi_push %r15
+.Lmul_body:
+___
+$code.=<<___ if ($addx);
+ cmp \$0x80100, %ecx
+ je .Lmul_montx
+___
+$code.=<<___;
+ mov $b_org, $b_ptr
+ mov 8*0($b_org), %rax
+ mov 8*0($a_ptr), $acc1
+ mov 8*1($a_ptr), $acc2
+ mov 8*2($a_ptr), $acc3
+ mov 8*3($a_ptr), $acc4
+
+ call __ecp_nistz256_mul_montq
+___
+$code.=<<___ if ($addx);
+ jmp .Lmul_mont_done
+
+.align 32
+.Lmul_montx:
+ mov $b_org, $b_ptr
+ mov 8*0($b_org), %rdx
+ mov 8*0($a_ptr), $acc1
+ mov 8*1($a_ptr), $acc2
+ mov 8*2($a_ptr), $acc3
+ mov 8*3($a_ptr), $acc4
+ lea -128($a_ptr), $a_ptr # control u-op density
+
+ call __ecp_nistz256_mul_montx
+___
+$code.=<<___;
+.Lmul_mont_done:
+ mov 0(%rsp),%r15
+.cfi_restore %r15
+ mov 8(%rsp),%r14
+.cfi_restore %r14
+ mov 16(%rsp),%r13
+.cfi_restore %r13
+ mov 24(%rsp),%r12
+.cfi_restore %r12
+ mov 32(%rsp),%rbx
+.cfi_restore %rbx
+ mov 40(%rsp),%rbp
+.cfi_restore %rbp
+ lea 48(%rsp),%rsp
+.cfi_adjust_cfa_offset -48
+.Lmul_epilogue:
+ ret
+.cfi_endproc
+.size ecp_nistz256_mul_mont,.-ecp_nistz256_mul_mont
+
+.type __ecp_nistz256_mul_montq,\@abi-omnipotent
+.align 32
+__ecp_nistz256_mul_montq:
+.cfi_startproc
+ ########################################################################
+ # Multiply a by b[0]
+ mov %rax, $t1
+ mulq $acc1
+ mov .Lpoly+8*1(%rip),$poly1
+ mov %rax, $acc0
+ mov $t1, %rax
+ mov %rdx, $acc1
+
+ mulq $acc2
+ mov .Lpoly+8*3(%rip),$poly3
+ add %rax, $acc1
+ mov $t1, %rax
+ adc \$0, %rdx
+ mov %rdx, $acc2
+
+ mulq $acc3
+ add %rax, $acc2
+ mov $t1, %rax
+ adc \$0, %rdx
+ mov %rdx, $acc3
+
+ mulq $acc4
+ add %rax, $acc3
+ mov $acc0, %rax
+ adc \$0, %rdx
+ xor $acc5, $acc5
+ mov %rdx, $acc4
+
+ ########################################################################
+ # First reduction step
+ # Basically now we want to multiply acc[0] by p256,
+ # and add the result to the acc.
+ # Due to the special form of p256 we do some optimizations
+ #
+ # acc[0] x p256[0..1] = acc[0] x 2^96 - acc[0]
+ # then we add acc[0] and get acc[0] x 2^96
+
+ mov $acc0, $t1
+ shl \$32, $acc0
+ mulq $poly3
+ shr \$32, $t1
+ add $acc0, $acc1 # +=acc[0]<<96
+ adc $t1, $acc2
+ adc %rax, $acc3
+ mov 8*1($b_ptr), %rax
+ adc %rdx, $acc4
+ adc \$0, $acc5
+ xor $acc0, $acc0
+
+ ########################################################################
+ # Multiply by b[1]
+ mov %rax, $t1
+ mulq 8*0($a_ptr)
+ add %rax, $acc1
+ mov $t1, %rax
+ adc \$0, %rdx
+ mov %rdx, $t0
+
+ mulq 8*1($a_ptr)
+ add $t0, $acc2
+ adc \$0, %rdx
+ add %rax, $acc2
+ mov $t1, %rax
+ adc \$0, %rdx
+ mov %rdx, $t0
+
+ mulq 8*2($a_ptr)
+ add $t0, $acc3
+ adc \$0, %rdx
+ add %rax, $acc3
+ mov $t1, %rax
+ adc \$0, %rdx
+ mov %rdx, $t0
+
+ mulq 8*3($a_ptr)
+ add $t0, $acc4
+ adc \$0, %rdx
+ add %rax, $acc4
+ mov $acc1, %rax
+ adc %rdx, $acc5
+ adc \$0, $acc0
+
+ ########################################################################
+ # Second reduction step
+ mov $acc1, $t1
+ shl \$32, $acc1
+ mulq $poly3
+ shr \$32, $t1
+ add $acc1, $acc2
+ adc $t1, $acc3
+ adc %rax, $acc4
+ mov 8*2($b_ptr), %rax
+ adc %rdx, $acc5
+ adc \$0, $acc0
+ xor $acc1, $acc1
+
+ ########################################################################
+ # Multiply by b[2]
+ mov %rax, $t1
+ mulq 8*0($a_ptr)
+ add %rax, $acc2
+ mov $t1, %rax
+ adc \$0, %rdx
+ mov %rdx, $t0
+
+ mulq 8*1($a_ptr)
+ add $t0, $acc3
+ adc \$0, %rdx
+ add %rax, $acc3
+ mov $t1, %rax
+ adc \$0, %rdx
+ mov %rdx, $t0
+
+ mulq 8*2($a_ptr)
+ add $t0, $acc4
+ adc \$0, %rdx
+ add %rax, $acc4
+ mov $t1, %rax
+ adc \$0, %rdx
+ mov %rdx, $t0
+
+ mulq 8*3($a_ptr)
+ add $t0, $acc5
+ adc \$0, %rdx
+ add %rax, $acc5
+ mov $acc2, %rax
+ adc %rdx, $acc0
+ adc \$0, $acc1
+
+ ########################################################################
+ # Third reduction step
+ mov $acc2, $t1
+ shl \$32, $acc2
+ mulq $poly3
+ shr \$32, $t1
+ add $acc2, $acc3
+ adc $t1, $acc4
+ adc %rax, $acc5
+ mov 8*3($b_ptr), %rax
+ adc %rdx, $acc0
+ adc \$0, $acc1
+ xor $acc2, $acc2
+
+ ########################################################################
+ # Multiply by b[3]
+ mov %rax, $t1
+ mulq 8*0($a_ptr)
+ add %rax, $acc3
+ mov $t1, %rax
+ adc \$0, %rdx
+ mov %rdx, $t0
+
+ mulq 8*1($a_ptr)
+ add $t0, $acc4
+ adc \$0, %rdx
+ add %rax, $acc4
+ mov $t1, %rax
+ adc \$0, %rdx
+ mov %rdx, $t0
+
+ mulq 8*2($a_ptr)
+ add $t0, $acc5
+ adc \$0, %rdx
+ add %rax, $acc5
+ mov $t1, %rax
+ adc \$0, %rdx
+ mov %rdx, $t0
+
+ mulq 8*3($a_ptr)
+ add $t0, $acc0
+ adc \$0, %rdx
+ add %rax, $acc0
+ mov $acc3, %rax
+ adc %rdx, $acc1
+ adc \$0, $acc2
+
+ ########################################################################
+ # Final reduction step
+ mov $acc3, $t1
+ shl \$32, $acc3
+ mulq $poly3
+ shr \$32, $t1
+ add $acc3, $acc4
+ adc $t1, $acc5
+ mov $acc4, $t0
+ adc %rax, $acc0
+ adc %rdx, $acc1
+ mov $acc5, $t1
+ adc \$0, $acc2
+
+ ########################################################################
+ # Branch-less conditional subtraction of P
+ sub \$-1, $acc4 # .Lpoly[0]
+ mov $acc0, $t2
+ sbb $poly1, $acc5 # .Lpoly[1]
+ sbb \$0, $acc0 # .Lpoly[2]
+ mov $acc1, $t3
+ sbb $poly3, $acc1 # .Lpoly[3]
+ sbb \$0, $acc2
+
+ cmovc $t0, $acc4
+ cmovc $t1, $acc5
+ mov $acc4, 8*0($r_ptr)
+ cmovc $t2, $acc0
+ mov $acc5, 8*1($r_ptr)
+ cmovc $t3, $acc1
+ mov $acc0, 8*2($r_ptr)
+ mov $acc1, 8*3($r_ptr)
+
+ ret
+.cfi_endproc
+.size __ecp_nistz256_mul_montq,.-__ecp_nistz256_mul_montq
+
+################################################################################
+# void ecp_nistz256_sqr_mont(
+# uint64_t res[4],
+# uint64_t a[4]);
+
+# we optimize the square according to S.Gueron and V.Krasnov,
+# "Speeding up Big-Number Squaring"
+.globl ecp_nistz256_sqr_mont
+.type ecp_nistz256_sqr_mont,\@function,2
+.align 32
+ecp_nistz256_sqr_mont:
+.cfi_startproc
+___
+$code.=<<___ if ($addx);
+ leaq OPENSSL_ia32cap_P(%rip), %rcx
+ mov 8(%rcx), %rcx
+ and \$0x80100, %ecx
+___
+$code.=<<___;
+ push %rbp
+.cfi_push %rbp
+ push %rbx
+.cfi_push %rbx
+ push %r12
+.cfi_push %r12
+ push %r13
+.cfi_push %r13
+ push %r14
+.cfi_push %r14
+ push %r15
+.cfi_push %r15
+.Lsqr_body:
+___
+$code.=<<___ if ($addx);
+ cmp \$0x80100, %ecx
+ je .Lsqr_montx
+___
+$code.=<<___;
+ mov 8*0($a_ptr), %rax
+ mov 8*1($a_ptr), $acc6
+ mov 8*2($a_ptr), $acc7
+ mov 8*3($a_ptr), $acc0
+
+ call __ecp_nistz256_sqr_montq
+___
+$code.=<<___ if ($addx);
+ jmp .Lsqr_mont_done
+
+.align 32
+.Lsqr_montx:
+ mov 8*0($a_ptr), %rdx
+ mov 8*1($a_ptr), $acc6
+ mov 8*2($a_ptr), $acc7
+ mov 8*3($a_ptr), $acc0
+ lea -128($a_ptr), $a_ptr # control u-op density
+
+ call __ecp_nistz256_sqr_montx
+___
+$code.=<<___;
+.Lsqr_mont_done:
+ mov 0(%rsp),%r15
+.cfi_restore %r15
+ mov 8(%rsp),%r14
+.cfi_restore %r14
+ mov 16(%rsp),%r13
+.cfi_restore %r13
+ mov 24(%rsp),%r12
+.cfi_restore %r12
+ mov 32(%rsp),%rbx
+.cfi_restore %rbx
+ mov 40(%rsp),%rbp
+.cfi_restore %rbp
+ lea 48(%rsp),%rsp
+.cfi_adjust_cfa_offset -48
+.Lsqr_epilogue:
+ ret
+.cfi_endproc
+.size ecp_nistz256_sqr_mont,.-ecp_nistz256_sqr_mont
+
+.type __ecp_nistz256_sqr_montq,\@abi-omnipotent
+.align 32
+__ecp_nistz256_sqr_montq:
+.cfi_startproc
+ mov %rax, $acc5
+ mulq $acc6 # a[1]*a[0]
+ mov %rax, $acc1
+ mov $acc7, %rax
+ mov %rdx, $acc2
+
+ mulq $acc5 # a[0]*a[2]
+ add %rax, $acc2
+ mov $acc0, %rax
+ adc \$0, %rdx
+ mov %rdx, $acc3
+
+ mulq $acc5 # a[0]*a[3]
+ add %rax, $acc3
+ mov $acc7, %rax
+ adc \$0, %rdx
+ mov %rdx, $acc4
+
+ #################################
+ mulq $acc6 # a[1]*a[2]
+ add %rax, $acc3
+ mov $acc0, %rax
+ adc \$0, %rdx
+ mov %rdx, $t1
+
+ mulq $acc6 # a[1]*a[3]
+ add %rax, $acc4
+ mov $acc0, %rax
+ adc \$0, %rdx
+ add $t1, $acc4
+ mov %rdx, $acc5
+ adc \$0, $acc5
+
+ #################################
+ mulq $acc7 # a[2]*a[3]
+ xor $acc7, $acc7
+ add %rax, $acc5
+ mov 8*0($a_ptr), %rax
+ mov %rdx, $acc6
+ adc \$0, $acc6
+
+ add $acc1, $acc1 # acc1:6<<1
+ adc $acc2, $acc2
+ adc $acc3, $acc3
+ adc $acc4, $acc4
+ adc $acc5, $acc5
+ adc $acc6, $acc6
+ adc \$0, $acc7
+
+ mulq %rax
+ mov %rax, $acc0
+ mov 8*1($a_ptr), %rax
+ mov %rdx, $t0
+
+ mulq %rax
+ add $t0, $acc1
+ adc %rax, $acc2
+ mov 8*2($a_ptr), %rax
+ adc \$0, %rdx
+ mov %rdx, $t0
+
+ mulq %rax
+ add $t0, $acc3
+ adc %rax, $acc4
+ mov 8*3($a_ptr), %rax
+ adc \$0, %rdx
+ mov %rdx, $t0
+
+ mulq %rax
+ add $t0, $acc5
+ adc %rax, $acc6
+ mov $acc0, %rax
+ adc %rdx, $acc7
+
+ mov .Lpoly+8*1(%rip), $a_ptr
+ mov .Lpoly+8*3(%rip), $t1
+
+ ##########################################
+ # Now the reduction
+ # First iteration
+ mov $acc0, $t0
+ shl \$32, $acc0
+ mulq $t1
+ shr \$32, $t0
+ add $acc0, $acc1 # +=acc[0]<<96
+ adc $t0, $acc2
+ adc %rax, $acc3
+ mov $acc1, %rax
+ adc \$0, %rdx
+
+ ##########################################
+ # Second iteration
+ mov $acc1, $t0
+ shl \$32, $acc1
+ mov %rdx, $acc0
+ mulq $t1
+ shr \$32, $t0
+ add $acc1, $acc2
+ adc $t0, $acc3
+ adc %rax, $acc0
+ mov $acc2, %rax
+ adc \$0, %rdx
+
+ ##########################################
+ # Third iteration
+ mov $acc2, $t0
+ shl \$32, $acc2
+ mov %rdx, $acc1
+ mulq $t1
+ shr \$32, $t0
+ add $acc2, $acc3
+ adc $t0, $acc0
+ adc %rax, $acc1
+ mov $acc3, %rax
+ adc \$0, %rdx
+
+ ###########################################
+ # Last iteration
+ mov $acc3, $t0
+ shl \$32, $acc3
+ mov %rdx, $acc2
+ mulq $t1
+ shr \$32, $t0
+ add $acc3, $acc0
+ adc $t0, $acc1
+ adc %rax, $acc2
+ adc \$0, %rdx
+ xor $acc3, $acc3
+
+ ############################################
+ # Add the rest of the acc
+ add $acc0, $acc4
+ adc $acc1, $acc5
+ mov $acc4, $acc0
+ adc $acc2, $acc6
+ adc %rdx, $acc7
+ mov $acc5, $acc1
+ adc \$0, $acc3
+
+ sub \$-1, $acc4 # .Lpoly[0]
+ mov $acc6, $acc2
+ sbb $a_ptr, $acc5 # .Lpoly[1]
+ sbb \$0, $acc6 # .Lpoly[2]
+ mov $acc7, $t0
+ sbb $t1, $acc7 # .Lpoly[3]
+ sbb \$0, $acc3
+
+ cmovc $acc0, $acc4
+ cmovc $acc1, $acc5
+ mov $acc4, 8*0($r_ptr)
+ cmovc $acc2, $acc6
+ mov $acc5, 8*1($r_ptr)
+ cmovc $t0, $acc7
+ mov $acc6, 8*2($r_ptr)
+ mov $acc7, 8*3($r_ptr)
+
+ ret
+.cfi_endproc
+.size __ecp_nistz256_sqr_montq,.-__ecp_nistz256_sqr_montq
+___
+
+if ($addx) {
+$code.=<<___;
+.type __ecp_nistz256_mul_montx,\@abi-omnipotent
+.align 32
+__ecp_nistz256_mul_montx:
+.cfi_startproc
+ ########################################################################
+ # Multiply by b[0]
+ mulx $acc1, $acc0, $acc1
+ mulx $acc2, $t0, $acc2
+ mov \$32, $poly1
+ xor $acc5, $acc5 # cf=0
+ mulx $acc3, $t1, $acc3
+ mov .Lpoly+8*3(%rip), $poly3
+ adc $t0, $acc1
+ mulx $acc4, $t0, $acc4
+ mov $acc0, %rdx
+ adc $t1, $acc2
+ shlx $poly1,$acc0,$t1
+ adc $t0, $acc3
+ shrx $poly1,$acc0,$t0
+ adc \$0, $acc4
+
+ ########################################################################
+ # First reduction step
+ add $t1, $acc1
+ adc $t0, $acc2
+
+ mulx $poly3, $t0, $t1
+ mov 8*1($b_ptr), %rdx
+ adc $t0, $acc3
+ adc $t1, $acc4
+ adc \$0, $acc5
+ xor $acc0, $acc0 # $acc0=0,cf=0,of=0
+
+ ########################################################################
+ # Multiply by b[1]
+ mulx 8*0+128($a_ptr), $t0, $t1
+ adcx $t0, $acc1
+ adox $t1, $acc2
+
+ mulx 8*1+128($a_ptr), $t0, $t1
+ adcx $t0, $acc2
+ adox $t1, $acc3
+
+ mulx 8*2+128($a_ptr), $t0, $t1
+ adcx $t0, $acc3
+ adox $t1, $acc4
+
+ mulx 8*3+128($a_ptr), $t0, $t1
+ mov $acc1, %rdx
+ adcx $t0, $acc4
+ shlx $poly1, $acc1, $t0
+ adox $t1, $acc5
+ shrx $poly1, $acc1, $t1
+
+ adcx $acc0, $acc5
+ adox $acc0, $acc0
+ adc \$0, $acc0
+
+ ########################################################################
+ # Second reduction step
+ add $t0, $acc2
+ adc $t1, $acc3
+
+ mulx $poly3, $t0, $t1
+ mov 8*2($b_ptr), %rdx
+ adc $t0, $acc4
+ adc $t1, $acc5
+ adc \$0, $acc0
+ xor $acc1 ,$acc1 # $acc1=0,cf=0,of=0
+
+ ########################################################################
+ # Multiply by b[2]
+ mulx 8*0+128($a_ptr), $t0, $t1
+ adcx $t0, $acc2
+ adox $t1, $acc3
+
+ mulx 8*1+128($a_ptr), $t0, $t1
+ adcx $t0, $acc3
+ adox $t1, $acc4
+
+ mulx 8*2+128($a_ptr), $t0, $t1
+ adcx $t0, $acc4
+ adox $t1, $acc5
+
+ mulx 8*3+128($a_ptr), $t0, $t1
+ mov $acc2, %rdx
+ adcx $t0, $acc5
+ shlx $poly1, $acc2, $t0
+ adox $t1, $acc0
+ shrx $poly1, $acc2, $t1
+
+ adcx $acc1, $acc0
+ adox $acc1, $acc1
+ adc \$0, $acc1
+
+ ########################################################################
+ # Third reduction step
+ add $t0, $acc3
+ adc $t1, $acc4
+
+ mulx $poly3, $t0, $t1
+ mov 8*3($b_ptr), %rdx
+ adc $t0, $acc5
+ adc $t1, $acc0
+ adc \$0, $acc1
+ xor $acc2, $acc2 # $acc2=0,cf=0,of=0
+
+ ########################################################################
+ # Multiply by b[3]
+ mulx 8*0+128($a_ptr), $t0, $t1
+ adcx $t0, $acc3
+ adox $t1, $acc4
+
+ mulx 8*1+128($a_ptr), $t0, $t1
+ adcx $t0, $acc4
+ adox $t1, $acc5
+
+ mulx 8*2+128($a_ptr), $t0, $t1
+ adcx $t0, $acc5
+ adox $t1, $acc0
+
+ mulx 8*3+128($a_ptr), $t0, $t1
+ mov $acc3, %rdx
+ adcx $t0, $acc0
+ shlx $poly1, $acc3, $t0
+ adox $t1, $acc1
+ shrx $poly1, $acc3, $t1
+
+ adcx $acc2, $acc1
+ adox $acc2, $acc2
+ adc \$0, $acc2
+
+ ########################################################################
+ # Fourth reduction step
+ add $t0, $acc4
+ adc $t1, $acc5
+
+ mulx $poly3, $t0, $t1
+ mov $acc4, $t2
+ mov .Lpoly+8*1(%rip), $poly1
+ adc $t0, $acc0
+ mov $acc5, $t3
+ adc $t1, $acc1
+ adc \$0, $acc2
+
+ ########################################################################
+ # Branch-less conditional subtraction of P
+ xor %eax, %eax
+ mov $acc0, $t0
+ sbb \$-1, $acc4 # .Lpoly[0]
+ sbb $poly1, $acc5 # .Lpoly[1]
+ sbb \$0, $acc0 # .Lpoly[2]
+ mov $acc1, $t1
+ sbb $poly3, $acc1 # .Lpoly[3]
+ sbb \$0, $acc2
+
+ cmovc $t2, $acc4
+ cmovc $t3, $acc5
+ mov $acc4, 8*0($r_ptr)
+ cmovc $t0, $acc0
+ mov $acc5, 8*1($r_ptr)
+ cmovc $t1, $acc1
+ mov $acc0, 8*2($r_ptr)
+ mov $acc1, 8*3($r_ptr)
+
+ ret
+.cfi_endproc
+.size __ecp_nistz256_mul_montx,.-__ecp_nistz256_mul_montx
+
+.type __ecp_nistz256_sqr_montx,\@abi-omnipotent
+.align 32
+__ecp_nistz256_sqr_montx:
+.cfi_startproc
+ mulx $acc6, $acc1, $acc2 # a[0]*a[1]
+ mulx $acc7, $t0, $acc3 # a[0]*a[2]
+ xor %eax, %eax
+ adc $t0, $acc2
+ mulx $acc0, $t1, $acc4 # a[0]*a[3]
+ mov $acc6, %rdx
+ adc $t1, $acc3
+ adc \$0, $acc4
+ xor $acc5, $acc5 # $acc5=0,cf=0,of=0
+
+ #################################
+ mulx $acc7, $t0, $t1 # a[1]*a[2]
+ adcx $t0, $acc3
+ adox $t1, $acc4
+
+ mulx $acc0, $t0, $t1 # a[1]*a[3]
+ mov $acc7, %rdx
+ adcx $t0, $acc4
+ adox $t1, $acc5
+ adc \$0, $acc5
+
+ #################################
+ mulx $acc0, $t0, $acc6 # a[2]*a[3]
+ mov 8*0+128($a_ptr), %rdx
+ xor $acc7, $acc7 # $acc7=0,cf=0,of=0
+ adcx $acc1, $acc1 # acc1:6<<1
+ adox $t0, $acc5
+ adcx $acc2, $acc2
+ adox $acc7, $acc6 # of=0
+
+ mulx %rdx, $acc0, $t1
+ mov 8*1+128($a_ptr), %rdx
+ adcx $acc3, $acc3
+ adox $t1, $acc1
+ adcx $acc4, $acc4
+ mulx %rdx, $t0, $t4
+ mov 8*2+128($a_ptr), %rdx
+ adcx $acc5, $acc5
+ adox $t0, $acc2
+ adcx $acc6, $acc6
+ .byte 0x67
+ mulx %rdx, $t0, $t1
+ mov 8*3+128($a_ptr), %rdx
+ adox $t4, $acc3
+ adcx $acc7, $acc7
+ adox $t0, $acc4
+ mov \$32, $a_ptr
+ adox $t1, $acc5
+ .byte 0x67,0x67
+ mulx %rdx, $t0, $t4
+ mov .Lpoly+8*3(%rip), %rdx
+ adox $t0, $acc6
+ shlx $a_ptr, $acc0, $t0
+ adox $t4, $acc7
+ shrx $a_ptr, $acc0, $t4
+ mov %rdx,$t1
+
+ # reduction step 1
+ add $t0, $acc1
+ adc $t4, $acc2
+
+ mulx $acc0, $t0, $acc0
+ adc $t0, $acc3
+ shlx $a_ptr, $acc1, $t0
+ adc \$0, $acc0
+ shrx $a_ptr, $acc1, $t4
+
+ # reduction step 2
+ add $t0, $acc2
+ adc $t4, $acc3
+
+ mulx $acc1, $t0, $acc1
+ adc $t0, $acc0
+ shlx $a_ptr, $acc2, $t0
+ adc \$0, $acc1
+ shrx $a_ptr, $acc2, $t4
+
+ # reduction step 3
+ add $t0, $acc3
+ adc $t4, $acc0
+
+ mulx $acc2, $t0, $acc2
+ adc $t0, $acc1
+ shlx $a_ptr, $acc3, $t0
+ adc \$0, $acc2
+ shrx $a_ptr, $acc3, $t4
+
+ # reduction step 4
+ add $t0, $acc0
+ adc $t4, $acc1
+
+ mulx $acc3, $t0, $acc3
+ adc $t0, $acc2
+ adc \$0, $acc3
+
+ xor $t3, $t3
+ add $acc0, $acc4 # accumulate upper half
+ mov .Lpoly+8*1(%rip), $a_ptr
+ adc $acc1, $acc5
+ mov $acc4, $acc0
+ adc $acc2, $acc6
+ adc $acc3, $acc7
+ mov $acc5, $acc1
+ adc \$0, $t3
+
+ sub \$-1, $acc4 # .Lpoly[0]
+ mov $acc6, $acc2
+ sbb $a_ptr, $acc5 # .Lpoly[1]
+ sbb \$0, $acc6 # .Lpoly[2]
+ mov $acc7, $acc3
+ sbb $t1, $acc7 # .Lpoly[3]
+ sbb \$0, $t3
+
+ cmovc $acc0, $acc4
+ cmovc $acc1, $acc5
+ mov $acc4, 8*0($r_ptr)
+ cmovc $acc2, $acc6
+ mov $acc5, 8*1($r_ptr)
+ cmovc $acc3, $acc7
+ mov $acc6, 8*2($r_ptr)
+ mov $acc7, 8*3($r_ptr)
+
+ ret
+.cfi_endproc
+.size __ecp_nistz256_sqr_montx,.-__ecp_nistz256_sqr_montx
+___
+}
+}
+{
+my ($val,$in_t,$index)=$win64?("%rcx","%rdx","%r8d"):("%rdi","%rsi","%edx");
+my ($ONE,$INDEX,$Ra,$Rb,$Rc,$Rd,$Re,$Rf)=map("%xmm$_",(0..7));
+my ($M0,$T0a,$T0b,$T0c,$T0d,$T0e,$T0f,$TMP0)=map("%xmm$_",(8..15));
+my ($M1,$T2a,$T2b,$TMP2,$M2,$T2a,$T2b,$TMP2)=map("%xmm$_",(8..15));
+
+$code.=<<___;
+################################################################################
+# void ecp_nistz256_select_w5(uint64_t *val, uint64_t *in_t, int index);
+.globl ecp_nistz256_select_w5
+.type ecp_nistz256_select_w5,\@abi-omnipotent
+.align 32
+ecp_nistz256_select_w5:
+.cfi_startproc
+___
+$code.=<<___ if ($avx>1);
+ leaq OPENSSL_ia32cap_P(%rip), %rax
+ mov 8(%rax), %rax
+ test \$`1<<5`, %eax
+ jnz .Lavx2_select_w5
+___
+$code.=<<___ if ($win64);
+ lea -0x88(%rsp), %rax
+.LSEH_begin_ecp_nistz256_select_w5:
+ .byte 0x48,0x8d,0x60,0xe0 #lea -0x20(%rax), %rsp
+ .byte 0x0f,0x29,0x70,0xe0 #movaps %xmm6, -0x20(%rax)
+ .byte 0x0f,0x29,0x78,0xf0 #movaps %xmm7, -0x10(%rax)
+ .byte 0x44,0x0f,0x29,0x00 #movaps %xmm8, 0(%rax)
+ .byte 0x44,0x0f,0x29,0x48,0x10 #movaps %xmm9, 0x10(%rax)
+ .byte 0x44,0x0f,0x29,0x50,0x20 #movaps %xmm10, 0x20(%rax)
+ .byte 0x44,0x0f,0x29,0x58,0x30 #movaps %xmm11, 0x30(%rax)
+ .byte 0x44,0x0f,0x29,0x60,0x40 #movaps %xmm12, 0x40(%rax)
+ .byte 0x44,0x0f,0x29,0x68,0x50 #movaps %xmm13, 0x50(%rax)
+ .byte 0x44,0x0f,0x29,0x70,0x60 #movaps %xmm14, 0x60(%rax)
+ .byte 0x44,0x0f,0x29,0x78,0x70 #movaps %xmm15, 0x70(%rax)
+___
+$code.=<<___;
+ movdqa .LOne(%rip), $ONE
+ movd $index, $INDEX
+
+ pxor $Ra, $Ra
+ pxor $Rb, $Rb
+ pxor $Rc, $Rc
+ pxor $Rd, $Rd
+ pxor $Re, $Re
+ pxor $Rf, $Rf
+
+ movdqa $ONE, $M0
+ pshufd \$0, $INDEX, $INDEX
+
+ mov \$16, %rax
+.Lselect_loop_sse_w5:
+
+ movdqa $M0, $TMP0
+ paddd $ONE, $M0
+ pcmpeqd $INDEX, $TMP0
+
+ movdqa 16*0($in_t), $T0a
+ movdqa 16*1($in_t), $T0b
+ movdqa 16*2($in_t), $T0c
+ movdqa 16*3($in_t), $T0d
+ movdqa 16*4($in_t), $T0e
+ movdqa 16*5($in_t), $T0f
+ lea 16*6($in_t), $in_t
+
+ pand $TMP0, $T0a
+ pand $TMP0, $T0b
+ por $T0a, $Ra
+ pand $TMP0, $T0c
+ por $T0b, $Rb
+ pand $TMP0, $T0d
+ por $T0c, $Rc
+ pand $TMP0, $T0e
+ por $T0d, $Rd
+ pand $TMP0, $T0f
+ por $T0e, $Re
+ por $T0f, $Rf
+
+ dec %rax
+ jnz .Lselect_loop_sse_w5
+
+ movdqu $Ra, 16*0($val)
+ movdqu $Rb, 16*1($val)
+ movdqu $Rc, 16*2($val)
+ movdqu $Rd, 16*3($val)
+ movdqu $Re, 16*4($val)
+ movdqu $Rf, 16*5($val)
+___
+$code.=<<___ if ($win64);
+ movaps (%rsp), %xmm6
+ movaps 0x10(%rsp), %xmm7
+ movaps 0x20(%rsp), %xmm8
+ movaps 0x30(%rsp), %xmm9
+ movaps 0x40(%rsp), %xmm10
+ movaps 0x50(%rsp), %xmm11
+ movaps 0x60(%rsp), %xmm12
+ movaps 0x70(%rsp), %xmm13
+ movaps 0x80(%rsp), %xmm14
+ movaps 0x90(%rsp), %xmm15
+ lea 0xa8(%rsp), %rsp
+___
+$code.=<<___;
+ ret
+.cfi_endproc
+.LSEH_end_ecp_nistz256_select_w5:
+.size ecp_nistz256_select_w5,.-ecp_nistz256_select_w5
+
+################################################################################
+# void ecp_nistz256_select_w7(uint64_t *val, uint64_t *in_t, int index);
+.globl ecp_nistz256_select_w7
+.type ecp_nistz256_select_w7,\@abi-omnipotent
+.align 32
+ecp_nistz256_select_w7:
+.cfi_startproc
+___
+$code.=<<___ if ($avx>1);
+ leaq OPENSSL_ia32cap_P(%rip), %rax
+ mov 8(%rax), %rax
+ test \$`1<<5`, %eax
+ jnz .Lavx2_select_w7
+___
+$code.=<<___ if ($win64);
+ lea -0x88(%rsp), %rax
+.LSEH_begin_ecp_nistz256_select_w7:
+ .byte 0x48,0x8d,0x60,0xe0 #lea -0x20(%rax), %rsp
+ .byte 0x0f,0x29,0x70,0xe0 #movaps %xmm6, -0x20(%rax)
+ .byte 0x0f,0x29,0x78,0xf0 #movaps %xmm7, -0x10(%rax)
+ .byte 0x44,0x0f,0x29,0x00 #movaps %xmm8, 0(%rax)
+ .byte 0x44,0x0f,0x29,0x48,0x10 #movaps %xmm9, 0x10(%rax)
+ .byte 0x44,0x0f,0x29,0x50,0x20 #movaps %xmm10, 0x20(%rax)
+ .byte 0x44,0x0f,0x29,0x58,0x30 #movaps %xmm11, 0x30(%rax)
+ .byte 0x44,0x0f,0x29,0x60,0x40 #movaps %xmm12, 0x40(%rax)
+ .byte 0x44,0x0f,0x29,0x68,0x50 #movaps %xmm13, 0x50(%rax)
+ .byte 0x44,0x0f,0x29,0x70,0x60 #movaps %xmm14, 0x60(%rax)
+ .byte 0x44,0x0f,0x29,0x78,0x70 #movaps %xmm15, 0x70(%rax)
+___
+$code.=<<___;
+ movdqa .LOne(%rip), $M0
+ movd $index, $INDEX
+
+ pxor $Ra, $Ra
+ pxor $Rb, $Rb
+ pxor $Rc, $Rc
+ pxor $Rd, $Rd
+
+ movdqa $M0, $ONE
+ pshufd \$0, $INDEX, $INDEX
+ mov \$64, %rax
+
+.Lselect_loop_sse_w7:
+ movdqa $M0, $TMP0
+ paddd $ONE, $M0
+ movdqa 16*0($in_t), $T0a
+ movdqa 16*1($in_t), $T0b
+ pcmpeqd $INDEX, $TMP0
+ movdqa 16*2($in_t), $T0c
+ movdqa 16*3($in_t), $T0d
+ lea 16*4($in_t), $in_t
+
+ pand $TMP0, $T0a
+ pand $TMP0, $T0b
+ por $T0a, $Ra
+ pand $TMP0, $T0c
+ por $T0b, $Rb
+ pand $TMP0, $T0d
+ por $T0c, $Rc
+ prefetcht0 255($in_t)
+ por $T0d, $Rd
+
+ dec %rax
+ jnz .Lselect_loop_sse_w7
+
+ movdqu $Ra, 16*0($val)
+ movdqu $Rb, 16*1($val)
+ movdqu $Rc, 16*2($val)
+ movdqu $Rd, 16*3($val)
+___
+$code.=<<___ if ($win64);
+ movaps (%rsp), %xmm6
+ movaps 0x10(%rsp), %xmm7
+ movaps 0x20(%rsp), %xmm8
+ movaps 0x30(%rsp), %xmm9
+ movaps 0x40(%rsp), %xmm10
+ movaps 0x50(%rsp), %xmm11
+ movaps 0x60(%rsp), %xmm12
+ movaps 0x70(%rsp), %xmm13
+ movaps 0x80(%rsp), %xmm14
+ movaps 0x90(%rsp), %xmm15
+ lea 0xa8(%rsp), %rsp
+___
+$code.=<<___;
+ ret
+.cfi_endproc
+.LSEH_end_ecp_nistz256_select_w7:
+.size ecp_nistz256_select_w7,.-ecp_nistz256_select_w7
+___
+}
+if ($avx>1) {
+my ($val,$in_t,$index)=$win64?("%rcx","%rdx","%r8d"):("%rdi","%rsi","%edx");
+my ($TWO,$INDEX,$Ra,$Rb,$Rc)=map("%ymm$_",(0..4));
+my ($M0,$T0a,$T0b,$T0c,$TMP0)=map("%ymm$_",(5..9));
+my ($M1,$T1a,$T1b,$T1c,$TMP1)=map("%ymm$_",(10..14));
+
+$code.=<<___;
+################################################################################
+# void ecp_nistz256_avx2_select_w5(uint64_t *val, uint64_t *in_t, int index);
+.type ecp_nistz256_avx2_select_w5,\@abi-omnipotent
+.align 32
+ecp_nistz256_avx2_select_w5:
+.cfi_startproc
+.Lavx2_select_w5:
+ vzeroupper
+___
+$code.=<<___ if ($win64);
+ lea -0x88(%rsp), %rax
+ mov %rsp,%r11
+.LSEH_begin_ecp_nistz256_avx2_select_w5:
+ .byte 0x48,0x8d,0x60,0xe0 # lea -0x20(%rax), %rsp
+ .byte 0xc5,0xf8,0x29,0x70,0xe0 # vmovaps %xmm6, -0x20(%rax)
+ .byte 0xc5,0xf8,0x29,0x78,0xf0 # vmovaps %xmm7, -0x10(%rax)
+ .byte 0xc5,0x78,0x29,0x40,0x00 # vmovaps %xmm8, 8(%rax)
+ .byte 0xc5,0x78,0x29,0x48,0x10 # vmovaps %xmm9, 0x10(%rax)
+ .byte 0xc5,0x78,0x29,0x50,0x20 # vmovaps %xmm10, 0x20(%rax)
+ .byte 0xc5,0x78,0x29,0x58,0x30 # vmovaps %xmm11, 0x30(%rax)
+ .byte 0xc5,0x78,0x29,0x60,0x40 # vmovaps %xmm12, 0x40(%rax)
+ .byte 0xc5,0x78,0x29,0x68,0x50 # vmovaps %xmm13, 0x50(%rax)
+ .byte 0xc5,0x78,0x29,0x70,0x60 # vmovaps %xmm14, 0x60(%rax)
+ .byte 0xc5,0x78,0x29,0x78,0x70 # vmovaps %xmm15, 0x70(%rax)
+___
+$code.=<<___;
+ vmovdqa .LTwo(%rip), $TWO
+
+ vpxor $Ra, $Ra, $Ra
+ vpxor $Rb, $Rb, $Rb
+ vpxor $Rc, $Rc, $Rc
+
+ vmovdqa .LOne(%rip), $M0
+ vmovdqa .LTwo(%rip), $M1
+
+ vmovd $index, %xmm1
+ vpermd $INDEX, $Ra, $INDEX
+
+ mov \$8, %rax
+.Lselect_loop_avx2_w5:
+
+ vmovdqa 32*0($in_t), $T0a
+ vmovdqa 32*1($in_t), $T0b
+ vmovdqa 32*2($in_t), $T0c
+
+ vmovdqa 32*3($in_t), $T1a
+ vmovdqa 32*4($in_t), $T1b
+ vmovdqa 32*5($in_t), $T1c
+
+ vpcmpeqd $INDEX, $M0, $TMP0
+ vpcmpeqd $INDEX, $M1, $TMP1
+
+ vpaddd $TWO, $M0, $M0
+ vpaddd $TWO, $M1, $M1
+ lea 32*6($in_t), $in_t
+
+ vpand $TMP0, $T0a, $T0a
+ vpand $TMP0, $T0b, $T0b
+ vpand $TMP0, $T0c, $T0c
+ vpand $TMP1, $T1a, $T1a
+ vpand $TMP1, $T1b, $T1b
+ vpand $TMP1, $T1c, $T1c
+
+ vpxor $T0a, $Ra, $Ra
+ vpxor $T0b, $Rb, $Rb
+ vpxor $T0c, $Rc, $Rc
+ vpxor $T1a, $Ra, $Ra
+ vpxor $T1b, $Rb, $Rb
+ vpxor $T1c, $Rc, $Rc
+
+ dec %rax
+ jnz .Lselect_loop_avx2_w5
+
+ vmovdqu $Ra, 32*0($val)
+ vmovdqu $Rb, 32*1($val)
+ vmovdqu $Rc, 32*2($val)
+ vzeroupper
+___
+$code.=<<___ if ($win64);
+ movaps (%rsp), %xmm6
+ movaps 0x10(%rsp), %xmm7
+ movaps 0x20(%rsp), %xmm8
+ movaps 0x30(%rsp), %xmm9
+ movaps 0x40(%rsp), %xmm10
+ movaps 0x50(%rsp), %xmm11
+ movaps 0x60(%rsp), %xmm12
+ movaps 0x70(%rsp), %xmm13
+ movaps 0x80(%rsp), %xmm14
+ movaps 0x90(%rsp), %xmm15
+ lea (%r11), %rsp
+___
+$code.=<<___;
+ ret
+.cfi_endproc
+.LSEH_end_ecp_nistz256_avx2_select_w5:
+.size ecp_nistz256_avx2_select_w5,.-ecp_nistz256_avx2_select_w5
+___
+}
+if ($avx>1) {
+my ($val,$in_t,$index)=$win64?("%rcx","%rdx","%r8d"):("%rdi","%rsi","%edx");
+my ($THREE,$INDEX,$Ra,$Rb)=map("%ymm$_",(0..3));
+my ($M0,$T0a,$T0b,$TMP0)=map("%ymm$_",(4..7));
+my ($M1,$T1a,$T1b,$TMP1)=map("%ymm$_",(8..11));
+my ($M2,$T2a,$T2b,$TMP2)=map("%ymm$_",(12..15));
+
+$code.=<<___;
+
+################################################################################
+# void ecp_nistz256_avx2_select_w7(uint64_t *val, uint64_t *in_t, int index);
+.globl ecp_nistz256_avx2_select_w7
+.type ecp_nistz256_avx2_select_w7,\@abi-omnipotent
+.align 32
+ecp_nistz256_avx2_select_w7:
+.cfi_startproc
+.Lavx2_select_w7:
+ vzeroupper
+___
+$code.=<<___ if ($win64);
+ mov %rsp,%r11
+ lea -0x88(%rsp), %rax
+.LSEH_begin_ecp_nistz256_avx2_select_w7:
+ .byte 0x48,0x8d,0x60,0xe0 # lea -0x20(%rax), %rsp
+ .byte 0xc5,0xf8,0x29,0x70,0xe0 # vmovaps %xmm6, -0x20(%rax)
+ .byte 0xc5,0xf8,0x29,0x78,0xf0 # vmovaps %xmm7, -0x10(%rax)
+ .byte 0xc5,0x78,0x29,0x40,0x00 # vmovaps %xmm8, 8(%rax)
+ .byte 0xc5,0x78,0x29,0x48,0x10 # vmovaps %xmm9, 0x10(%rax)
+ .byte 0xc5,0x78,0x29,0x50,0x20 # vmovaps %xmm10, 0x20(%rax)
+ .byte 0xc5,0x78,0x29,0x58,0x30 # vmovaps %xmm11, 0x30(%rax)
+ .byte 0xc5,0x78,0x29,0x60,0x40 # vmovaps %xmm12, 0x40(%rax)
+ .byte 0xc5,0x78,0x29,0x68,0x50 # vmovaps %xmm13, 0x50(%rax)
+ .byte 0xc5,0x78,0x29,0x70,0x60 # vmovaps %xmm14, 0x60(%rax)
+ .byte 0xc5,0x78,0x29,0x78,0x70 # vmovaps %xmm15, 0x70(%rax)
+___
+$code.=<<___;
+ vmovdqa .LThree(%rip), $THREE
+
+ vpxor $Ra, $Ra, $Ra
+ vpxor $Rb, $Rb, $Rb
+
+ vmovdqa .LOne(%rip), $M0
+ vmovdqa .LTwo(%rip), $M1
+ vmovdqa .LThree(%rip), $M2
+
+ vmovd $index, %xmm1
+ vpermd $INDEX, $Ra, $INDEX
+ # Skip index = 0, because it is implicitly the point at infinity
+
+ mov \$21, %rax
+.Lselect_loop_avx2_w7:
+
+ vmovdqa 32*0($in_t), $T0a
+ vmovdqa 32*1($in_t), $T0b
+
+ vmovdqa 32*2($in_t), $T1a
+ vmovdqa 32*3($in_t), $T1b
+
+ vmovdqa 32*4($in_t), $T2a
+ vmovdqa 32*5($in_t), $T2b
+
+ vpcmpeqd $INDEX, $M0, $TMP0
+ vpcmpeqd $INDEX, $M1, $TMP1
+ vpcmpeqd $INDEX, $M2, $TMP2
+
+ vpaddd $THREE, $M0, $M0
+ vpaddd $THREE, $M1, $M1
+ vpaddd $THREE, $M2, $M2
+ lea 32*6($in_t), $in_t
+
+ vpand $TMP0, $T0a, $T0a
+ vpand $TMP0, $T0b, $T0b
+ vpand $TMP1, $T1a, $T1a
+ vpand $TMP1, $T1b, $T1b
+ vpand $TMP2, $T2a, $T2a
+ vpand $TMP2, $T2b, $T2b
+
+ vpxor $T0a, $Ra, $Ra
+ vpxor $T0b, $Rb, $Rb
+ vpxor $T1a, $Ra, $Ra
+ vpxor $T1b, $Rb, $Rb
+ vpxor $T2a, $Ra, $Ra
+ vpxor $T2b, $Rb, $Rb
+
+ dec %rax
+ jnz .Lselect_loop_avx2_w7
+
+
+ vmovdqa 32*0($in_t), $T0a
+ vmovdqa 32*1($in_t), $T0b
+
+ vpcmpeqd $INDEX, $M0, $TMP0
+
+ vpand $TMP0, $T0a, $T0a
+ vpand $TMP0, $T0b, $T0b
+
+ vpxor $T0a, $Ra, $Ra
+ vpxor $T0b, $Rb, $Rb
+
+ vmovdqu $Ra, 32*0($val)
+ vmovdqu $Rb, 32*1($val)
+ vzeroupper
+___
+$code.=<<___ if ($win64);
+ movaps (%rsp), %xmm6
+ movaps 0x10(%rsp), %xmm7
+ movaps 0x20(%rsp), %xmm8
+ movaps 0x30(%rsp), %xmm9
+ movaps 0x40(%rsp), %xmm10
+ movaps 0x50(%rsp), %xmm11
+ movaps 0x60(%rsp), %xmm12
+ movaps 0x70(%rsp), %xmm13
+ movaps 0x80(%rsp), %xmm14
+ movaps 0x90(%rsp), %xmm15
+ lea (%r11), %rsp
+___
+$code.=<<___;
+ ret
+.cfi_endproc
+.LSEH_end_ecp_nistz256_avx2_select_w7:
+.size ecp_nistz256_avx2_select_w7,.-ecp_nistz256_avx2_select_w7
+___
+} else {
+$code.=<<___;
+.globl ecp_nistz256_avx2_select_w7
+.type ecp_nistz256_avx2_select_w7,\@function,3
+.align 32
+ecp_nistz256_avx2_select_w7:
+ .byte 0x0f,0x0b # ud2
+ ret
+.size ecp_nistz256_avx2_select_w7,.-ecp_nistz256_avx2_select_w7
+___
+}
+{{{
+########################################################################
+# This block implements higher level point_double, point_add and
+# point_add_affine. The key to performance in this case is to allow
+# out-of-order execution logic to overlap computations from next step
+# with tail processing from current step. By using tailored calling
+# sequence we minimize inter-step overhead to give processor better
+# shot at overlapping operations...
+#
+# You will notice that input data is copied to stack. Trouble is that
+# there are no registers to spare for holding original pointers and
+# reloading them, pointers, would create undesired dependencies on
+# effective addresses calculation paths. In other words it's too done
+# to favour out-of-order execution logic.
+# <appro@openssl.org>
+
+my ($r_ptr,$a_ptr,$b_org,$b_ptr)=("%rdi","%rsi","%rdx","%rbx");
+my ($acc0,$acc1,$acc2,$acc3,$acc4,$acc5,$acc6,$acc7)=map("%r$_",(8..15));
+my ($t0,$t1,$t2,$t3,$t4)=("%rax","%rbp","%rcx",$acc4,$acc4);
+my ($poly1,$poly3)=($acc6,$acc7);
+
+sub load_for_mul () {
+my ($a,$b,$src0) = @_;
+my $bias = $src0 eq "%rax" ? 0 : -128;
+
+" mov $b, $src0
+ lea $b, $b_ptr
+ mov 8*0+$a, $acc1
+ mov 8*1+$a, $acc2
+ lea $bias+$a, $a_ptr
+ mov 8*2+$a, $acc3
+ mov 8*3+$a, $acc4"
+}
+
+sub load_for_sqr () {
+my ($a,$src0) = @_;
+my $bias = $src0 eq "%rax" ? 0 : -128;
+
+" mov 8*0+$a, $src0
+ mov 8*1+$a, $acc6
+ lea $bias+$a, $a_ptr
+ mov 8*2+$a, $acc7
+ mov 8*3+$a, $acc0"
+}
+
+ {
+########################################################################
+# operate in 4-5-0-1 "name space" that matches multiplication output
+#
+my ($a0,$a1,$a2,$a3,$t3,$t4)=($acc4,$acc5,$acc0,$acc1,$acc2,$acc3);
+
+$code.=<<___;
+.type __ecp_nistz256_add_toq,\@abi-omnipotent
+.align 32
+__ecp_nistz256_add_toq:
+.cfi_startproc
+ xor $t4,$t4
+ add 8*0($b_ptr), $a0
+ adc 8*1($b_ptr), $a1
+ mov $a0, $t0
+ adc 8*2($b_ptr), $a2
+ adc 8*3($b_ptr), $a3
+ mov $a1, $t1
+ adc \$0, $t4
+
+ sub \$-1, $a0
+ mov $a2, $t2
+ sbb $poly1, $a1
+ sbb \$0, $a2
+ mov $a3, $t3
+ sbb $poly3, $a3
+ sbb \$0, $t4
+
+ cmovc $t0, $a0
+ cmovc $t1, $a1
+ mov $a0, 8*0($r_ptr)
+ cmovc $t2, $a2
+ mov $a1, 8*1($r_ptr)
+ cmovc $t3, $a3
+ mov $a2, 8*2($r_ptr)
+ mov $a3, 8*3($r_ptr)
+
+ ret
+.cfi_endproc
+.size __ecp_nistz256_add_toq,.-__ecp_nistz256_add_toq
+
+.type __ecp_nistz256_sub_fromq,\@abi-omnipotent
+.align 32
+__ecp_nistz256_sub_fromq:
+.cfi_startproc
+ sub 8*0($b_ptr), $a0
+ sbb 8*1($b_ptr), $a1
+ mov $a0, $t0
+ sbb 8*2($b_ptr), $a2
+ sbb 8*3($b_ptr), $a3
+ mov $a1, $t1
+ sbb $t4, $t4
+
+ add \$-1, $a0
+ mov $a2, $t2
+ adc $poly1, $a1
+ adc \$0, $a2
+ mov $a3, $t3
+ adc $poly3, $a3
+ test $t4, $t4
+
+ cmovz $t0, $a0
+ cmovz $t1, $a1
+ mov $a0, 8*0($r_ptr)
+ cmovz $t2, $a2
+ mov $a1, 8*1($r_ptr)
+ cmovz $t3, $a3
+ mov $a2, 8*2($r_ptr)
+ mov $a3, 8*3($r_ptr)
+
+ ret
+.cfi_endproc
+.size __ecp_nistz256_sub_fromq,.-__ecp_nistz256_sub_fromq
+
+.type __ecp_nistz256_subq,\@abi-omnipotent
+.align 32
+__ecp_nistz256_subq:
+.cfi_startproc
+ sub $a0, $t0
+ sbb $a1, $t1
+ mov $t0, $a0
+ sbb $a2, $t2
+ sbb $a3, $t3
+ mov $t1, $a1
+ sbb $t4, $t4
+
+ add \$-1, $t0
+ mov $t2, $a2
+ adc $poly1, $t1
+ adc \$0, $t2
+ mov $t3, $a3
+ adc $poly3, $t3
+ test $t4, $t4
+
+ cmovnz $t0, $a0
+ cmovnz $t1, $a1
+ cmovnz $t2, $a2
+ cmovnz $t3, $a3
+
+ ret
+.cfi_endproc
+.size __ecp_nistz256_subq,.-__ecp_nistz256_subq
+
+.type __ecp_nistz256_mul_by_2q,\@abi-omnipotent
+.align 32
+__ecp_nistz256_mul_by_2q:
+.cfi_startproc
+ xor $t4, $t4
+ add $a0, $a0 # a0:a3+a0:a3
+ adc $a1, $a1
+ mov $a0, $t0
+ adc $a2, $a2
+ adc $a3, $a3
+ mov $a1, $t1
+ adc \$0, $t4
+
+ sub \$-1, $a0
+ mov $a2, $t2
+ sbb $poly1, $a1
+ sbb \$0, $a2
+ mov $a3, $t3
+ sbb $poly3, $a3
+ sbb \$0, $t4
+
+ cmovc $t0, $a0
+ cmovc $t1, $a1
+ mov $a0, 8*0($r_ptr)
+ cmovc $t2, $a2
+ mov $a1, 8*1($r_ptr)
+ cmovc $t3, $a3
+ mov $a2, 8*2($r_ptr)
+ mov $a3, 8*3($r_ptr)
+
+ ret
+.cfi_endproc
+.size __ecp_nistz256_mul_by_2q,.-__ecp_nistz256_mul_by_2q
+___
+ }
+sub gen_double () {
+ my $x = shift;
+ my ($src0,$sfx,$bias);
+ my ($S,$M,$Zsqr,$in_x,$tmp0)=map(32*$_,(0..4));
+
+ if ($x ne "x") {
+ $src0 = "%rax";
+ $sfx = "";
+ $bias = 0;
+
+$code.=<<___;
+.globl ecp_nistz256_point_double
+.type ecp_nistz256_point_double,\@function,2
+.align 32
+ecp_nistz256_point_double:
+.cfi_startproc
+___
+$code.=<<___ if ($addx);
+ leaq OPENSSL_ia32cap_P(%rip), %rcx
+ mov 8(%rcx), %rcx
+ and \$0x80100, %ecx
+ cmp \$0x80100, %ecx
+ je .Lpoint_doublex
+___
+ } else {
+ $src0 = "%rdx";
+ $sfx = "x";
+ $bias = 128;
+
+$code.=<<___;
+.type ecp_nistz256_point_doublex,\@function,2
+.align 32
+ecp_nistz256_point_doublex:
+.cfi_startproc
+.Lpoint_doublex:
+___
+ }
+$code.=<<___;
+ push %rbp
+.cfi_push %rbp
+ push %rbx
+.cfi_push %rbx
+ push %r12
+.cfi_push %r12
+ push %r13
+.cfi_push %r13
+ push %r14
+.cfi_push %r14
+ push %r15
+.cfi_push %r15
+ sub \$32*5+8, %rsp
+.cfi_adjust_cfa_offset 32*5+8
+.Lpoint_double${x}_body:
+
+.Lpoint_double_shortcut$x:
+ movdqu 0x00($a_ptr), %xmm0 # copy *(P256_POINT *)$a_ptr.x
+ mov $a_ptr, $b_ptr # backup copy
+ movdqu 0x10($a_ptr), %xmm1
+ mov 0x20+8*0($a_ptr), $acc4 # load in_y in "5-4-0-1" order
+ mov 0x20+8*1($a_ptr), $acc5
+ mov 0x20+8*2($a_ptr), $acc0
+ mov 0x20+8*3($a_ptr), $acc1
+ mov .Lpoly+8*1(%rip), $poly1
+ mov .Lpoly+8*3(%rip), $poly3
+ movdqa %xmm0, $in_x(%rsp)
+ movdqa %xmm1, $in_x+0x10(%rsp)
+ lea 0x20($r_ptr), $acc2
+ lea 0x40($r_ptr), $acc3
+ movq $r_ptr, %xmm0
+ movq $acc2, %xmm1
+ movq $acc3, %xmm2
+
+ lea $S(%rsp), $r_ptr
+ call __ecp_nistz256_mul_by_2$x # p256_mul_by_2(S, in_y);
+
+ mov 0x40+8*0($a_ptr), $src0
+ mov 0x40+8*1($a_ptr), $acc6
+ mov 0x40+8*2($a_ptr), $acc7
+ mov 0x40+8*3($a_ptr), $acc0
+ lea 0x40-$bias($a_ptr), $a_ptr
+ lea $Zsqr(%rsp), $r_ptr
+ call __ecp_nistz256_sqr_mont$x # p256_sqr_mont(Zsqr, in_z);
+
+ `&load_for_sqr("$S(%rsp)", "$src0")`
+ lea $S(%rsp), $r_ptr
+ call __ecp_nistz256_sqr_mont$x # p256_sqr_mont(S, S);
+
+ mov 0x20($b_ptr), $src0 # $b_ptr is still valid
+ mov 0x40+8*0($b_ptr), $acc1
+ mov 0x40+8*1($b_ptr), $acc2
+ mov 0x40+8*2($b_ptr), $acc3
+ mov 0x40+8*3($b_ptr), $acc4
+ lea 0x40-$bias($b_ptr), $a_ptr
+ lea 0x20($b_ptr), $b_ptr
+ movq %xmm2, $r_ptr
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(res_z, in_z, in_y);
+ call __ecp_nistz256_mul_by_2$x # p256_mul_by_2(res_z, res_z);
+
+ mov $in_x+8*0(%rsp), $acc4 # "5-4-0-1" order
+ mov $in_x+8*1(%rsp), $acc5
+ lea $Zsqr(%rsp), $b_ptr
+ mov $in_x+8*2(%rsp), $acc0
+ mov $in_x+8*3(%rsp), $acc1
+ lea $M(%rsp), $r_ptr
+ call __ecp_nistz256_add_to$x # p256_add(M, in_x, Zsqr);
+
+ mov $in_x+8*0(%rsp), $acc4 # "5-4-0-1" order
+ mov $in_x+8*1(%rsp), $acc5
+ lea $Zsqr(%rsp), $b_ptr
+ mov $in_x+8*2(%rsp), $acc0
+ mov $in_x+8*3(%rsp), $acc1
+ lea $Zsqr(%rsp), $r_ptr
+ call __ecp_nistz256_sub_from$x # p256_sub(Zsqr, in_x, Zsqr);
+
+ `&load_for_sqr("$S(%rsp)", "$src0")`
+ movq %xmm1, $r_ptr
+ call __ecp_nistz256_sqr_mont$x # p256_sqr_mont(res_y, S);
+___
+{
+######## ecp_nistz256_div_by_2(res_y, res_y); ##########################
+# operate in 4-5-6-7 "name space" that matches squaring output
+#
+my ($poly1,$poly3)=($a_ptr,$t1);
+my ($a0,$a1,$a2,$a3,$t3,$t4,$t1)=($acc4,$acc5,$acc6,$acc7,$acc0,$acc1,$acc2);
+
+$code.=<<___;
+ xor $t4, $t4
+ mov $a0, $t0
+ add \$-1, $a0
+ mov $a1, $t1
+ adc $poly1, $a1
+ mov $a2, $t2
+ adc \$0, $a2
+ mov $a3, $t3
+ adc $poly3, $a3
+ adc \$0, $t4
+ xor $a_ptr, $a_ptr # borrow $a_ptr
+ test \$1, $t0
+
+ cmovz $t0, $a0
+ cmovz $t1, $a1
+ cmovz $t2, $a2
+ cmovz $t3, $a3
+ cmovz $a_ptr, $t4
+
+ mov $a1, $t0 # a0:a3>>1
+ shr \$1, $a0
+ shl \$63, $t0
+ mov $a2, $t1
+ shr \$1, $a1
+ or $t0, $a0
+ shl \$63, $t1
+ mov $a3, $t2
+ shr \$1, $a2
+ or $t1, $a1
+ shl \$63, $t2
+ mov $a0, 8*0($r_ptr)
+ shr \$1, $a3
+ mov $a1, 8*1($r_ptr)
+ shl \$63, $t4
+ or $t2, $a2
+ or $t4, $a3
+ mov $a2, 8*2($r_ptr)
+ mov $a3, 8*3($r_ptr)
+___
+}
+$code.=<<___;
+ `&load_for_mul("$M(%rsp)", "$Zsqr(%rsp)", "$src0")`
+ lea $M(%rsp), $r_ptr
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(M, M, Zsqr);
+
+ lea $tmp0(%rsp), $r_ptr
+ call __ecp_nistz256_mul_by_2$x
+
+ lea $M(%rsp), $b_ptr
+ lea $M(%rsp), $r_ptr
+ call __ecp_nistz256_add_to$x # p256_mul_by_3(M, M);
+
+ `&load_for_mul("$S(%rsp)", "$in_x(%rsp)", "$src0")`
+ lea $S(%rsp), $r_ptr
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(S, S, in_x);
+
+ lea $tmp0(%rsp), $r_ptr
+ call __ecp_nistz256_mul_by_2$x # p256_mul_by_2(tmp0, S);
+
+ `&load_for_sqr("$M(%rsp)", "$src0")`
+ movq %xmm0, $r_ptr
+ call __ecp_nistz256_sqr_mont$x # p256_sqr_mont(res_x, M);
+
+ lea $tmp0(%rsp), $b_ptr
+ mov $acc6, $acc0 # harmonize sqr output and sub input
+ mov $acc7, $acc1
+ mov $a_ptr, $poly1
+ mov $t1, $poly3
+ call __ecp_nistz256_sub_from$x # p256_sub(res_x, res_x, tmp0);
+
+ mov $S+8*0(%rsp), $t0
+ mov $S+8*1(%rsp), $t1
+ mov $S+8*2(%rsp), $t2
+ mov $S+8*3(%rsp), $acc2 # "4-5-0-1" order
+ lea $S(%rsp), $r_ptr
+ call __ecp_nistz256_sub$x # p256_sub(S, S, res_x);
+
+ mov $M(%rsp), $src0
+ lea $M(%rsp), $b_ptr
+ mov $acc4, $acc6 # harmonize sub output and mul input
+ xor %ecx, %ecx
+ mov $acc4, $S+8*0(%rsp) # have to save:-(
+ mov $acc5, $acc2
+ mov $acc5, $S+8*1(%rsp)
+ cmovz $acc0, $acc3
+ mov $acc0, $S+8*2(%rsp)
+ lea $S-$bias(%rsp), $a_ptr
+ cmovz $acc1, $acc4
+ mov $acc1, $S+8*3(%rsp)
+ mov $acc6, $acc1
+ lea $S(%rsp), $r_ptr
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(S, S, M);
+
+ movq %xmm1, $b_ptr
+ movq %xmm1, $r_ptr
+ call __ecp_nistz256_sub_from$x # p256_sub(res_y, S, res_y);
+
+ lea 32*5+56(%rsp), %rsi
+.cfi_def_cfa %rsi,8
+ mov -48(%rsi),%r15
+.cfi_restore %r15
+ mov -40(%rsi),%r14
+.cfi_restore %r14
+ mov -32(%rsi),%r13
+.cfi_restore %r13
+ mov -24(%rsi),%r12
+.cfi_restore %r12
+ mov -16(%rsi),%rbx
+.cfi_restore %rbx
+ mov -8(%rsi),%rbp
+.cfi_restore %rbp
+ lea (%rsi),%rsp
+.cfi_def_cfa_register %rsp
+.Lpoint_double${x}_epilogue:
+ ret
+.cfi_endproc
+.size ecp_nistz256_point_double$sfx,.-ecp_nistz256_point_double$sfx
+___
+}
+&gen_double("q");
+
+sub gen_add () {
+ my $x = shift;
+ my ($src0,$sfx,$bias);
+ my ($H,$Hsqr,$R,$Rsqr,$Hcub,
+ $U1,$U2,$S1,$S2,
+ $res_x,$res_y,$res_z,
+ $in1_x,$in1_y,$in1_z,
+ $in2_x,$in2_y,$in2_z)=map(32*$_,(0..17));
+ my ($Z1sqr, $Z2sqr) = ($Hsqr, $Rsqr);
+
+ if ($x ne "x") {
+ $src0 = "%rax";
+ $sfx = "";
+ $bias = 0;
+
+$code.=<<___;
+.globl ecp_nistz256_point_add
+.type ecp_nistz256_point_add,\@function,3
+.align 32
+ecp_nistz256_point_add:
+.cfi_startproc
+___
+$code.=<<___ if ($addx);
+ leaq OPENSSL_ia32cap_P(%rip), %rcx
+ mov 8(%rcx), %rcx
+ and \$0x80100, %ecx
+ cmp \$0x80100, %ecx
+ je .Lpoint_addx
+___
+ } else {
+ $src0 = "%rdx";
+ $sfx = "x";
+ $bias = 128;
+
+$code.=<<___;
+.type ecp_nistz256_point_addx,\@function,3
+.align 32
+ecp_nistz256_point_addx:
+.cfi_startproc
+.Lpoint_addx:
+___
+ }
+$code.=<<___;
+ push %rbp
+.cfi_push %rbp
+ push %rbx
+.cfi_push %rbx
+ push %r12
+.cfi_push %r12
+ push %r13
+.cfi_push %r13
+ push %r14
+.cfi_push %r14
+ push %r15
+.cfi_push %r15
+ sub \$32*18+8, %rsp
+.cfi_adjust_cfa_offset 32*18+8
+.Lpoint_add${x}_body:
+
+ movdqu 0x00($a_ptr), %xmm0 # copy *(P256_POINT *)$a_ptr
+ movdqu 0x10($a_ptr), %xmm1
+ movdqu 0x20($a_ptr), %xmm2
+ movdqu 0x30($a_ptr), %xmm3
+ movdqu 0x40($a_ptr), %xmm4
+ movdqu 0x50($a_ptr), %xmm5
+ mov $a_ptr, $b_ptr # reassign
+ mov $b_org, $a_ptr # reassign
+ movdqa %xmm0, $in1_x(%rsp)
+ movdqa %xmm1, $in1_x+0x10(%rsp)
+ movdqa %xmm2, $in1_y(%rsp)
+ movdqa %xmm3, $in1_y+0x10(%rsp)
+ movdqa %xmm4, $in1_z(%rsp)
+ movdqa %xmm5, $in1_z+0x10(%rsp)
+ por %xmm4, %xmm5
+
+ movdqu 0x00($a_ptr), %xmm0 # copy *(P256_POINT *)$b_ptr
+ pshufd \$0xb1, %xmm5, %xmm3
+ movdqu 0x10($a_ptr), %xmm1
+ movdqu 0x20($a_ptr), %xmm2
+ por %xmm3, %xmm5
+ movdqu 0x30($a_ptr), %xmm3
+ mov 0x40+8*0($a_ptr), $src0 # load original in2_z
+ mov 0x40+8*1($a_ptr), $acc6
+ mov 0x40+8*2($a_ptr), $acc7
+ mov 0x40+8*3($a_ptr), $acc0
+ movdqa %xmm0, $in2_x(%rsp)
+ pshufd \$0x1e, %xmm5, %xmm4
+ movdqa %xmm1, $in2_x+0x10(%rsp)
+ movdqu 0x40($a_ptr),%xmm0 # in2_z again
+ movdqu 0x50($a_ptr),%xmm1
+ movdqa %xmm2, $in2_y(%rsp)
+ movdqa %xmm3, $in2_y+0x10(%rsp)
+ por %xmm4, %xmm5
+ pxor %xmm4, %xmm4
+ por %xmm0, %xmm1
+ movq $r_ptr, %xmm0 # save $r_ptr
+
+ lea 0x40-$bias($a_ptr), $a_ptr # $a_ptr is still valid
+ mov $src0, $in2_z+8*0(%rsp) # make in2_z copy
+ mov $acc6, $in2_z+8*1(%rsp)
+ mov $acc7, $in2_z+8*2(%rsp)
+ mov $acc0, $in2_z+8*3(%rsp)
+ lea $Z2sqr(%rsp), $r_ptr # Z2^2
+ call __ecp_nistz256_sqr_mont$x # p256_sqr_mont(Z2sqr, in2_z);
+
+ pcmpeqd %xmm4, %xmm5
+ pshufd \$0xb1, %xmm1, %xmm4
+ por %xmm1, %xmm4
+ pshufd \$0, %xmm5, %xmm5 # in1infty
+ pshufd \$0x1e, %xmm4, %xmm3
+ por %xmm3, %xmm4
+ pxor %xmm3, %xmm3
+ pcmpeqd %xmm3, %xmm4
+ pshufd \$0, %xmm4, %xmm4 # in2infty
+ mov 0x40+8*0($b_ptr), $src0 # load original in1_z
+ mov 0x40+8*1($b_ptr), $acc6
+ mov 0x40+8*2($b_ptr), $acc7
+ mov 0x40+8*3($b_ptr), $acc0
+ movq $b_ptr, %xmm1
+
+ lea 0x40-$bias($b_ptr), $a_ptr
+ lea $Z1sqr(%rsp), $r_ptr # Z1^2
+ call __ecp_nistz256_sqr_mont$x # p256_sqr_mont(Z1sqr, in1_z);
+
+ `&load_for_mul("$Z2sqr(%rsp)", "$in2_z(%rsp)", "$src0")`
+ lea $S1(%rsp), $r_ptr # S1 = Z2^3
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(S1, Z2sqr, in2_z);
+
+ `&load_for_mul("$Z1sqr(%rsp)", "$in1_z(%rsp)", "$src0")`
+ lea $S2(%rsp), $r_ptr # S2 = Z1^3
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(S2, Z1sqr, in1_z);
+
+ `&load_for_mul("$S1(%rsp)", "$in1_y(%rsp)", "$src0")`
+ lea $S1(%rsp), $r_ptr # S1 = Y1*Z2^3
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(S1, S1, in1_y);
+
+ `&load_for_mul("$S2(%rsp)", "$in2_y(%rsp)", "$src0")`
+ lea $S2(%rsp), $r_ptr # S2 = Y2*Z1^3
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(S2, S2, in2_y);
+
+ lea $S1(%rsp), $b_ptr
+ lea $R(%rsp), $r_ptr # R = S2 - S1
+ call __ecp_nistz256_sub_from$x # p256_sub(R, S2, S1);
+
+ or $acc5, $acc4 # see if result is zero
+ movdqa %xmm4, %xmm2
+ or $acc0, $acc4
+ or $acc1, $acc4
+ por %xmm5, %xmm2 # in1infty || in2infty
+ movq $acc4, %xmm3
+
+ `&load_for_mul("$Z2sqr(%rsp)", "$in1_x(%rsp)", "$src0")`
+ lea $U1(%rsp), $r_ptr # U1 = X1*Z2^2
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(U1, in1_x, Z2sqr);
+
+ `&load_for_mul("$Z1sqr(%rsp)", "$in2_x(%rsp)", "$src0")`
+ lea $U2(%rsp), $r_ptr # U2 = X2*Z1^2
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(U2, in2_x, Z1sqr);
+
+ lea $U1(%rsp), $b_ptr
+ lea $H(%rsp), $r_ptr # H = U2 - U1
+ call __ecp_nistz256_sub_from$x # p256_sub(H, U2, U1);
+
+ or $acc5, $acc4 # see if result is zero
+ or $acc0, $acc4
+ or $acc1, $acc4 # !is_equal(U1, U2)
+
+ movq %xmm2, $acc0
+ movq %xmm3, $acc1
+ or $acc0, $acc4
+ .byte 0x3e # predict taken
+ jnz .Ladd_proceed$x # !is_equal(U1, U2) || in1infty || in2infty
+
+ # We now know A = B or A = -B and neither is infinity. Compare the
+ # y-coordinates via S1 and S2.
+ test $acc1, $acc1
+ jz .Ladd_double$x # is_equal(S1, S2)
+
+ # A = -B, so the result is infinity.
+ #
+ # TODO(davidben): Does .Ladd_proceed handle this case? It seems to, in
+ # which case we should eliminate this special-case and simplify the
+ # timing analysis.
+ movq %xmm0, $r_ptr # restore $r_ptr
+ pxor %xmm0, %xmm0
+ movdqu %xmm0, 0x00($r_ptr)
+ movdqu %xmm0, 0x10($r_ptr)
+ movdqu %xmm0, 0x20($r_ptr)
+ movdqu %xmm0, 0x30($r_ptr)
+ movdqu %xmm0, 0x40($r_ptr)
+ movdqu %xmm0, 0x50($r_ptr)
+ jmp .Ladd_done$x
+
+.align 32
+.Ladd_double$x:
+ movq %xmm1, $a_ptr # restore $a_ptr
+ movq %xmm0, $r_ptr # restore $r_ptr
+ add \$`32*(18-5)`, %rsp # difference in frame sizes
+.cfi_adjust_cfa_offset `-32*(18-5)`
+ jmp .Lpoint_double_shortcut$x
+.cfi_adjust_cfa_offset `32*(18-5)`
+
+.align 32
+.Ladd_proceed$x:
+ `&load_for_sqr("$R(%rsp)", "$src0")`
+ lea $Rsqr(%rsp), $r_ptr # R^2
+ call __ecp_nistz256_sqr_mont$x # p256_sqr_mont(Rsqr, R);
+
+ `&load_for_mul("$H(%rsp)", "$in1_z(%rsp)", "$src0")`
+ lea $res_z(%rsp), $r_ptr # Z3 = H*Z1*Z2
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(res_z, H, in1_z);
+
+ `&load_for_sqr("$H(%rsp)", "$src0")`
+ lea $Hsqr(%rsp), $r_ptr # H^2
+ call __ecp_nistz256_sqr_mont$x # p256_sqr_mont(Hsqr, H);
+
+ `&load_for_mul("$res_z(%rsp)", "$in2_z(%rsp)", "$src0")`
+ lea $res_z(%rsp), $r_ptr # Z3 = H*Z1*Z2
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(res_z, res_z, in2_z);
+
+ `&load_for_mul("$Hsqr(%rsp)", "$H(%rsp)", "$src0")`
+ lea $Hcub(%rsp), $r_ptr # H^3
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(Hcub, Hsqr, H);
+
+ `&load_for_mul("$Hsqr(%rsp)", "$U1(%rsp)", "$src0")`
+ lea $U2(%rsp), $r_ptr # U1*H^2
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(U2, U1, Hsqr);
+___
+{
+#######################################################################
+# operate in 4-5-0-1 "name space" that matches multiplication output
+#
+my ($acc0,$acc1,$acc2,$acc3,$t3,$t4)=($acc4,$acc5,$acc0,$acc1,$acc2,$acc3);
+my ($poly1, $poly3)=($acc6,$acc7);
+
+$code.=<<___;
+ #lea $U2(%rsp), $a_ptr
+ #lea $Hsqr(%rsp), $r_ptr # 2*U1*H^2
+ #call __ecp_nistz256_mul_by_2 # ecp_nistz256_mul_by_2(Hsqr, U2);
+
+ xor $t4, $t4
+ add $acc0, $acc0 # a0:a3+a0:a3
+ lea $Rsqr(%rsp), $a_ptr
+ adc $acc1, $acc1
+ mov $acc0, $t0
+ adc $acc2, $acc2
+ adc $acc3, $acc3
+ mov $acc1, $t1
+ adc \$0, $t4
+
+ sub \$-1, $acc0
+ mov $acc2, $t2
+ sbb $poly1, $acc1
+ sbb \$0, $acc2
+ mov $acc3, $t3
+ sbb $poly3, $acc3
+ sbb \$0, $t4
+
+ cmovc $t0, $acc0
+ mov 8*0($a_ptr), $t0
+ cmovc $t1, $acc1
+ mov 8*1($a_ptr), $t1
+ cmovc $t2, $acc2
+ mov 8*2($a_ptr), $t2
+ cmovc $t3, $acc3
+ mov 8*3($a_ptr), $t3
+
+ call __ecp_nistz256_sub$x # p256_sub(res_x, Rsqr, Hsqr);
+
+ lea $Hcub(%rsp), $b_ptr
+ lea $res_x(%rsp), $r_ptr
+ call __ecp_nistz256_sub_from$x # p256_sub(res_x, res_x, Hcub);
+
+ mov $U2+8*0(%rsp), $t0
+ mov $U2+8*1(%rsp), $t1
+ mov $U2+8*2(%rsp), $t2
+ mov $U2+8*3(%rsp), $t3
+ lea $res_y(%rsp), $r_ptr
+
+ call __ecp_nistz256_sub$x # p256_sub(res_y, U2, res_x);
+
+ mov $acc0, 8*0($r_ptr) # save the result, as
+ mov $acc1, 8*1($r_ptr) # __ecp_nistz256_sub doesn't
+ mov $acc2, 8*2($r_ptr)
+ mov $acc3, 8*3($r_ptr)
+___
+}
+$code.=<<___;
+ `&load_for_mul("$S1(%rsp)", "$Hcub(%rsp)", "$src0")`
+ lea $S2(%rsp), $r_ptr
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(S2, S1, Hcub);
+
+ `&load_for_mul("$R(%rsp)", "$res_y(%rsp)", "$src0")`
+ lea $res_y(%rsp), $r_ptr
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(res_y, R, res_y);
+
+ lea $S2(%rsp), $b_ptr
+ lea $res_y(%rsp), $r_ptr
+ call __ecp_nistz256_sub_from$x # p256_sub(res_y, res_y, S2);
+
+ movq %xmm0, $r_ptr # restore $r_ptr
+
+ movdqa %xmm5, %xmm0 # copy_conditional(res_z, in2_z, in1infty);
+ movdqa %xmm5, %xmm1
+ pandn $res_z(%rsp), %xmm0
+ movdqa %xmm5, %xmm2
+ pandn $res_z+0x10(%rsp), %xmm1
+ movdqa %xmm5, %xmm3
+ pand $in2_z(%rsp), %xmm2
+ pand $in2_z+0x10(%rsp), %xmm3
+ por %xmm0, %xmm2
+ por %xmm1, %xmm3
+
+ movdqa %xmm4, %xmm0 # copy_conditional(res_z, in1_z, in2infty);
+ movdqa %xmm4, %xmm1
+ pandn %xmm2, %xmm0
+ movdqa %xmm4, %xmm2
+ pandn %xmm3, %xmm1
+ movdqa %xmm4, %xmm3
+ pand $in1_z(%rsp), %xmm2
+ pand $in1_z+0x10(%rsp), %xmm3
+ por %xmm0, %xmm2
+ por %xmm1, %xmm3
+ movdqu %xmm2, 0x40($r_ptr)
+ movdqu %xmm3, 0x50($r_ptr)
+
+ movdqa %xmm5, %xmm0 # copy_conditional(res_x, in2_x, in1infty);
+ movdqa %xmm5, %xmm1
+ pandn $res_x(%rsp), %xmm0
+ movdqa %xmm5, %xmm2
+ pandn $res_x+0x10(%rsp), %xmm1
+ movdqa %xmm5, %xmm3
+ pand $in2_x(%rsp), %xmm2
+ pand $in2_x+0x10(%rsp), %xmm3
+ por %xmm0, %xmm2
+ por %xmm1, %xmm3
+
+ movdqa %xmm4, %xmm0 # copy_conditional(res_x, in1_x, in2infty);
+ movdqa %xmm4, %xmm1
+ pandn %xmm2, %xmm0
+ movdqa %xmm4, %xmm2
+ pandn %xmm3, %xmm1
+ movdqa %xmm4, %xmm3
+ pand $in1_x(%rsp), %xmm2
+ pand $in1_x+0x10(%rsp), %xmm3
+ por %xmm0, %xmm2
+ por %xmm1, %xmm3
+ movdqu %xmm2, 0x00($r_ptr)
+ movdqu %xmm3, 0x10($r_ptr)
+
+ movdqa %xmm5, %xmm0 # copy_conditional(res_y, in2_y, in1infty);
+ movdqa %xmm5, %xmm1
+ pandn $res_y(%rsp), %xmm0
+ movdqa %xmm5, %xmm2
+ pandn $res_y+0x10(%rsp), %xmm1
+ movdqa %xmm5, %xmm3
+ pand $in2_y(%rsp), %xmm2
+ pand $in2_y+0x10(%rsp), %xmm3
+ por %xmm0, %xmm2
+ por %xmm1, %xmm3
+
+ movdqa %xmm4, %xmm0 # copy_conditional(res_y, in1_y, in2infty);
+ movdqa %xmm4, %xmm1
+ pandn %xmm2, %xmm0
+ movdqa %xmm4, %xmm2
+ pandn %xmm3, %xmm1
+ movdqa %xmm4, %xmm3
+ pand $in1_y(%rsp), %xmm2
+ pand $in1_y+0x10(%rsp), %xmm3
+ por %xmm0, %xmm2
+ por %xmm1, %xmm3
+ movdqu %xmm2, 0x20($r_ptr)
+ movdqu %xmm3, 0x30($r_ptr)
+
+.Ladd_done$x:
+ lea 32*18+56(%rsp), %rsi
+.cfi_def_cfa %rsi,8
+ mov -48(%rsi),%r15
+.cfi_restore %r15
+ mov -40(%rsi),%r14
+.cfi_restore %r14
+ mov -32(%rsi),%r13
+.cfi_restore %r13
+ mov -24(%rsi),%r12
+.cfi_restore %r12
+ mov -16(%rsi),%rbx
+.cfi_restore %rbx
+ mov -8(%rsi),%rbp
+.cfi_restore %rbp
+ lea (%rsi),%rsp
+.cfi_def_cfa_register %rsp
+.Lpoint_add${x}_epilogue:
+ ret
+.cfi_endproc
+.size ecp_nistz256_point_add$sfx,.-ecp_nistz256_point_add$sfx
+___
+}
+&gen_add("q");
+
+sub gen_add_affine () {
+ my $x = shift;
+ my ($src0,$sfx,$bias);
+ my ($U2,$S2,$H,$R,$Hsqr,$Hcub,$Rsqr,
+ $res_x,$res_y,$res_z,
+ $in1_x,$in1_y,$in1_z,
+ $in2_x,$in2_y)=map(32*$_,(0..14));
+ my $Z1sqr = $S2;
+
+ if ($x ne "x") {
+ $src0 = "%rax";
+ $sfx = "";
+ $bias = 0;
+
+$code.=<<___;
+.globl ecp_nistz256_point_add_affine
+.type ecp_nistz256_point_add_affine,\@function,3
+.align 32
+ecp_nistz256_point_add_affine:
+.cfi_startproc
+___
+$code.=<<___ if ($addx);
+ leaq OPENSSL_ia32cap_P(%rip), %rcx
+ mov 8(%rcx), %rcx
+ and \$0x80100, %ecx
+ cmp \$0x80100, %ecx
+ je .Lpoint_add_affinex
+___
+ } else {
+ $src0 = "%rdx";
+ $sfx = "x";
+ $bias = 128;
+
+$code.=<<___;
+.type ecp_nistz256_point_add_affinex,\@function,3
+.align 32
+ecp_nistz256_point_add_affinex:
+.cfi_startproc
+.Lpoint_add_affinex:
+___
+ }
+$code.=<<___;
+ push %rbp
+.cfi_push %rbp
+ push %rbx
+.cfi_push %rbx
+ push %r12
+.cfi_push %r12
+ push %r13
+.cfi_push %r13
+ push %r14
+.cfi_push %r14
+ push %r15
+.cfi_push %r15
+ sub \$32*15+8, %rsp
+.cfi_adjust_cfa_offset 32*15+8
+.Ladd_affine${x}_body:
+
+ movdqu 0x00($a_ptr), %xmm0 # copy *(P256_POINT *)$a_ptr
+ mov $b_org, $b_ptr # reassign
+ movdqu 0x10($a_ptr), %xmm1
+ movdqu 0x20($a_ptr), %xmm2
+ movdqu 0x30($a_ptr), %xmm3
+ movdqu 0x40($a_ptr), %xmm4
+ movdqu 0x50($a_ptr), %xmm5
+ mov 0x40+8*0($a_ptr), $src0 # load original in1_z
+ mov 0x40+8*1($a_ptr), $acc6
+ mov 0x40+8*2($a_ptr), $acc7
+ mov 0x40+8*3($a_ptr), $acc0
+ movdqa %xmm0, $in1_x(%rsp)
+ movdqa %xmm1, $in1_x+0x10(%rsp)
+ movdqa %xmm2, $in1_y(%rsp)
+ movdqa %xmm3, $in1_y+0x10(%rsp)
+ movdqa %xmm4, $in1_z(%rsp)
+ movdqa %xmm5, $in1_z+0x10(%rsp)
+ por %xmm4, %xmm5
+
+ movdqu 0x00($b_ptr), %xmm0 # copy *(P256_POINT_AFFINE *)$b_ptr
+ pshufd \$0xb1, %xmm5, %xmm3
+ movdqu 0x10($b_ptr), %xmm1
+ movdqu 0x20($b_ptr), %xmm2
+ por %xmm3, %xmm5
+ movdqu 0x30($b_ptr), %xmm3
+ movdqa %xmm0, $in2_x(%rsp)
+ pshufd \$0x1e, %xmm5, %xmm4
+ movdqa %xmm1, $in2_x+0x10(%rsp)
+ por %xmm0, %xmm1
+ movq $r_ptr, %xmm0 # save $r_ptr
+ movdqa %xmm2, $in2_y(%rsp)
+ movdqa %xmm3, $in2_y+0x10(%rsp)
+ por %xmm2, %xmm3
+ por %xmm4, %xmm5
+ pxor %xmm4, %xmm4
+ por %xmm1, %xmm3
+
+ lea 0x40-$bias($a_ptr), $a_ptr # $a_ptr is still valid
+ lea $Z1sqr(%rsp), $r_ptr # Z1^2
+ call __ecp_nistz256_sqr_mont$x # p256_sqr_mont(Z1sqr, in1_z);
+
+ pcmpeqd %xmm4, %xmm5
+ pshufd \$0xb1, %xmm3, %xmm4
+ mov 0x00($b_ptr), $src0 # $b_ptr is still valid
+ #lea 0x00($b_ptr), $b_ptr
+ mov $acc4, $acc1 # harmonize sqr output and mul input
+ por %xmm3, %xmm4
+ pshufd \$0, %xmm5, %xmm5 # in1infty
+ pshufd \$0x1e, %xmm4, %xmm3
+ mov $acc5, $acc2
+ por %xmm3, %xmm4
+ pxor %xmm3, %xmm3
+ mov $acc6, $acc3
+ pcmpeqd %xmm3, %xmm4
+ pshufd \$0, %xmm4, %xmm4 # in2infty
+
+ lea $Z1sqr-$bias(%rsp), $a_ptr
+ mov $acc7, $acc4
+ lea $U2(%rsp), $r_ptr # U2 = X2*Z1^2
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(U2, Z1sqr, in2_x);
+
+ lea $in1_x(%rsp), $b_ptr
+ lea $H(%rsp), $r_ptr # H = U2 - U1
+ call __ecp_nistz256_sub_from$x # p256_sub(H, U2, in1_x);
+
+ `&load_for_mul("$Z1sqr(%rsp)", "$in1_z(%rsp)", "$src0")`
+ lea $S2(%rsp), $r_ptr # S2 = Z1^3
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(S2, Z1sqr, in1_z);
+
+ `&load_for_mul("$H(%rsp)", "$in1_z(%rsp)", "$src0")`
+ lea $res_z(%rsp), $r_ptr # Z3 = H*Z1*Z2
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(res_z, H, in1_z);
+
+ `&load_for_mul("$S2(%rsp)", "$in2_y(%rsp)", "$src0")`
+ lea $S2(%rsp), $r_ptr # S2 = Y2*Z1^3
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(S2, S2, in2_y);
+
+ lea $in1_y(%rsp), $b_ptr
+ lea $R(%rsp), $r_ptr # R = S2 - S1
+ call __ecp_nistz256_sub_from$x # p256_sub(R, S2, in1_y);
+
+ `&load_for_sqr("$H(%rsp)", "$src0")`
+ lea $Hsqr(%rsp), $r_ptr # H^2
+ call __ecp_nistz256_sqr_mont$x # p256_sqr_mont(Hsqr, H);
+
+ `&load_for_sqr("$R(%rsp)", "$src0")`
+ lea $Rsqr(%rsp), $r_ptr # R^2
+ call __ecp_nistz256_sqr_mont$x # p256_sqr_mont(Rsqr, R);
+
+ `&load_for_mul("$H(%rsp)", "$Hsqr(%rsp)", "$src0")`
+ lea $Hcub(%rsp), $r_ptr # H^3
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(Hcub, Hsqr, H);
+
+ `&load_for_mul("$Hsqr(%rsp)", "$in1_x(%rsp)", "$src0")`
+ lea $U2(%rsp), $r_ptr # U1*H^2
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(U2, in1_x, Hsqr);
+___
+{
+#######################################################################
+# operate in 4-5-0-1 "name space" that matches multiplication output
+#
+my ($acc0,$acc1,$acc2,$acc3,$t3,$t4)=($acc4,$acc5,$acc0,$acc1,$acc2,$acc3);
+my ($poly1, $poly3)=($acc6,$acc7);
+
+$code.=<<___;
+ #lea $U2(%rsp), $a_ptr
+ #lea $Hsqr(%rsp), $r_ptr # 2*U1*H^2
+ #call __ecp_nistz256_mul_by_2 # ecp_nistz256_mul_by_2(Hsqr, U2);
+
+ xor $t4, $t4
+ add $acc0, $acc0 # a0:a3+a0:a3
+ lea $Rsqr(%rsp), $a_ptr
+ adc $acc1, $acc1
+ mov $acc0, $t0
+ adc $acc2, $acc2
+ adc $acc3, $acc3
+ mov $acc1, $t1
+ adc \$0, $t4
+
+ sub \$-1, $acc0
+ mov $acc2, $t2
+ sbb $poly1, $acc1
+ sbb \$0, $acc2
+ mov $acc3, $t3
+ sbb $poly3, $acc3
+ sbb \$0, $t4
+
+ cmovc $t0, $acc0
+ mov 8*0($a_ptr), $t0
+ cmovc $t1, $acc1
+ mov 8*1($a_ptr), $t1
+ cmovc $t2, $acc2
+ mov 8*2($a_ptr), $t2
+ cmovc $t3, $acc3
+ mov 8*3($a_ptr), $t3
+
+ call __ecp_nistz256_sub$x # p256_sub(res_x, Rsqr, Hsqr);
+
+ lea $Hcub(%rsp), $b_ptr
+ lea $res_x(%rsp), $r_ptr
+ call __ecp_nistz256_sub_from$x # p256_sub(res_x, res_x, Hcub);
+
+ mov $U2+8*0(%rsp), $t0
+ mov $U2+8*1(%rsp), $t1
+ mov $U2+8*2(%rsp), $t2
+ mov $U2+8*3(%rsp), $t3
+ lea $H(%rsp), $r_ptr
+
+ call __ecp_nistz256_sub$x # p256_sub(H, U2, res_x);
+
+ mov $acc0, 8*0($r_ptr) # save the result, as
+ mov $acc1, 8*1($r_ptr) # __ecp_nistz256_sub doesn't
+ mov $acc2, 8*2($r_ptr)
+ mov $acc3, 8*3($r_ptr)
+___
+}
+$code.=<<___;
+ `&load_for_mul("$Hcub(%rsp)", "$in1_y(%rsp)", "$src0")`
+ lea $S2(%rsp), $r_ptr
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(S2, Hcub, in1_y);
+
+ `&load_for_mul("$H(%rsp)", "$R(%rsp)", "$src0")`
+ lea $H(%rsp), $r_ptr
+ call __ecp_nistz256_mul_mont$x # p256_mul_mont(H, H, R);
+
+ lea $S2(%rsp), $b_ptr
+ lea $res_y(%rsp), $r_ptr
+ call __ecp_nistz256_sub_from$x # p256_sub(res_y, H, S2);
+
+ movq %xmm0, $r_ptr # restore $r_ptr
+
+ movdqa %xmm5, %xmm0 # copy_conditional(res_z, ONE, in1infty);
+ movdqa %xmm5, %xmm1
+ pandn $res_z(%rsp), %xmm0
+ movdqa %xmm5, %xmm2
+ pandn $res_z+0x10(%rsp), %xmm1
+ movdqa %xmm5, %xmm3
+ pand .LONE_mont(%rip), %xmm2
+ pand .LONE_mont+0x10(%rip), %xmm3
+ por %xmm0, %xmm2
+ por %xmm1, %xmm3
+
+ movdqa %xmm4, %xmm0 # copy_conditional(res_z, in1_z, in2infty);
+ movdqa %xmm4, %xmm1
+ pandn %xmm2, %xmm0
+ movdqa %xmm4, %xmm2
+ pandn %xmm3, %xmm1
+ movdqa %xmm4, %xmm3
+ pand $in1_z(%rsp), %xmm2
+ pand $in1_z+0x10(%rsp), %xmm3
+ por %xmm0, %xmm2
+ por %xmm1, %xmm3
+ movdqu %xmm2, 0x40($r_ptr)
+ movdqu %xmm3, 0x50($r_ptr)
+
+ movdqa %xmm5, %xmm0 # copy_conditional(res_x, in2_x, in1infty);
+ movdqa %xmm5, %xmm1
+ pandn $res_x(%rsp), %xmm0
+ movdqa %xmm5, %xmm2
+ pandn $res_x+0x10(%rsp), %xmm1
+ movdqa %xmm5, %xmm3
+ pand $in2_x(%rsp), %xmm2
+ pand $in2_x+0x10(%rsp), %xmm3
+ por %xmm0, %xmm2
+ por %xmm1, %xmm3
+
+ movdqa %xmm4, %xmm0 # copy_conditional(res_x, in1_x, in2infty);
+ movdqa %xmm4, %xmm1
+ pandn %xmm2, %xmm0
+ movdqa %xmm4, %xmm2
+ pandn %xmm3, %xmm1
+ movdqa %xmm4, %xmm3
+ pand $in1_x(%rsp), %xmm2
+ pand $in1_x+0x10(%rsp), %xmm3
+ por %xmm0, %xmm2
+ por %xmm1, %xmm3
+ movdqu %xmm2, 0x00($r_ptr)
+ movdqu %xmm3, 0x10($r_ptr)
+
+ movdqa %xmm5, %xmm0 # copy_conditional(res_y, in2_y, in1infty);
+ movdqa %xmm5, %xmm1
+ pandn $res_y(%rsp), %xmm0
+ movdqa %xmm5, %xmm2
+ pandn $res_y+0x10(%rsp), %xmm1
+ movdqa %xmm5, %xmm3
+ pand $in2_y(%rsp), %xmm2
+ pand $in2_y+0x10(%rsp), %xmm3
+ por %xmm0, %xmm2
+ por %xmm1, %xmm3
+
+ movdqa %xmm4, %xmm0 # copy_conditional(res_y, in1_y, in2infty);
+ movdqa %xmm4, %xmm1
+ pandn %xmm2, %xmm0
+ movdqa %xmm4, %xmm2
+ pandn %xmm3, %xmm1
+ movdqa %xmm4, %xmm3
+ pand $in1_y(%rsp), %xmm2
+ pand $in1_y+0x10(%rsp), %xmm3
+ por %xmm0, %xmm2
+ por %xmm1, %xmm3
+ movdqu %xmm2, 0x20($r_ptr)
+ movdqu %xmm3, 0x30($r_ptr)
+
+ lea 32*15+56(%rsp), %rsi
+.cfi_def_cfa %rsi,8
+ mov -48(%rsi),%r15
+.cfi_restore %r15
+ mov -40(%rsi),%r14
+.cfi_restore %r14
+ mov -32(%rsi),%r13
+.cfi_restore %r13
+ mov -24(%rsi),%r12
+.cfi_restore %r12
+ mov -16(%rsi),%rbx
+.cfi_restore %rbx
+ mov -8(%rsi),%rbp
+.cfi_restore %rbp
+ lea (%rsi),%rsp
+.cfi_def_cfa_register %rsp
+.Ladd_affine${x}_epilogue:
+ ret
+.cfi_endproc
+.size ecp_nistz256_point_add_affine$sfx,.-ecp_nistz256_point_add_affine$sfx
+___
+}
+&gen_add_affine("q");
+
+########################################################################
+# AD*X magic
+#
+if ($addx) { {
+########################################################################
+# operate in 4-5-0-1 "name space" that matches multiplication output
+#
+my ($a0,$a1,$a2,$a3,$t3,$t4)=($acc4,$acc5,$acc0,$acc1,$acc2,$acc3);
+
+$code.=<<___;
+.type __ecp_nistz256_add_tox,\@abi-omnipotent
+.align 32
+__ecp_nistz256_add_tox:
+.cfi_startproc
+ xor $t4, $t4
+ adc 8*0($b_ptr), $a0
+ adc 8*1($b_ptr), $a1
+ mov $a0, $t0
+ adc 8*2($b_ptr), $a2
+ adc 8*3($b_ptr), $a3
+ mov $a1, $t1
+ adc \$0, $t4
+
+ xor $t3, $t3
+ sbb \$-1, $a0
+ mov $a2, $t2
+ sbb $poly1, $a1
+ sbb \$0, $a2
+ mov $a3, $t3
+ sbb $poly3, $a3
+ sbb \$0, $t4
+
+ cmovc $t0, $a0
+ cmovc $t1, $a1
+ mov $a0, 8*0($r_ptr)
+ cmovc $t2, $a2
+ mov $a1, 8*1($r_ptr)
+ cmovc $t3, $a3
+ mov $a2, 8*2($r_ptr)
+ mov $a3, 8*3($r_ptr)
+
+ ret
+.cfi_endproc
+.size __ecp_nistz256_add_tox,.-__ecp_nistz256_add_tox
+
+.type __ecp_nistz256_sub_fromx,\@abi-omnipotent
+.align 32
+__ecp_nistz256_sub_fromx:
+.cfi_startproc
+ xor $t4, $t4
+ sbb 8*0($b_ptr), $a0
+ sbb 8*1($b_ptr), $a1
+ mov $a0, $t0
+ sbb 8*2($b_ptr), $a2
+ sbb 8*3($b_ptr), $a3
+ mov $a1, $t1
+ sbb \$0, $t4
+
+ xor $t3, $t3
+ adc \$-1, $a0
+ mov $a2, $t2
+ adc $poly1, $a1
+ adc \$0, $a2
+ mov $a3, $t3
+ adc $poly3, $a3
+
+ bt \$0, $t4
+ cmovnc $t0, $a0
+ cmovnc $t1, $a1
+ mov $a0, 8*0($r_ptr)
+ cmovnc $t2, $a2
+ mov $a1, 8*1($r_ptr)
+ cmovnc $t3, $a3
+ mov $a2, 8*2($r_ptr)
+ mov $a3, 8*3($r_ptr)
+
+ ret
+.cfi_endproc
+.size __ecp_nistz256_sub_fromx,.-__ecp_nistz256_sub_fromx
+
+.type __ecp_nistz256_subx,\@abi-omnipotent
+.align 32
+__ecp_nistz256_subx:
+.cfi_startproc
+ xor $t4, $t4
+ sbb $a0, $t0
+ sbb $a1, $t1
+ mov $t0, $a0
+ sbb $a2, $t2
+ sbb $a3, $t3
+ mov $t1, $a1
+ sbb \$0, $t4
+
+ xor $a3 ,$a3
+ adc \$-1, $t0
+ mov $t2, $a2
+ adc $poly1, $t1
+ adc \$0, $t2
+ mov $t3, $a3
+ adc $poly3, $t3
+
+ bt \$0, $t4
+ cmovc $t0, $a0
+ cmovc $t1, $a1
+ cmovc $t2, $a2
+ cmovc $t3, $a3
+
+ ret
+.cfi_endproc
+.size __ecp_nistz256_subx,.-__ecp_nistz256_subx
+
+.type __ecp_nistz256_mul_by_2x,\@abi-omnipotent
+.align 32
+__ecp_nistz256_mul_by_2x:
+.cfi_startproc
+ xor $t4, $t4
+ adc $a0, $a0 # a0:a3+a0:a3
+ adc $a1, $a1
+ mov $a0, $t0
+ adc $a2, $a2
+ adc $a3, $a3
+ mov $a1, $t1
+ adc \$0, $t4
+
+ xor $t3, $t3
+ sbb \$-1, $a0
+ mov $a2, $t2
+ sbb $poly1, $a1
+ sbb \$0, $a2
+ mov $a3, $t3
+ sbb $poly3, $a3
+ sbb \$0, $t4
+
+ cmovc $t0, $a0
+ cmovc $t1, $a1
+ mov $a0, 8*0($r_ptr)
+ cmovc $t2, $a2
+ mov $a1, 8*1($r_ptr)
+ cmovc $t3, $a3
+ mov $a2, 8*2($r_ptr)
+ mov $a3, 8*3($r_ptr)
+
+ ret
+.cfi_endproc
+.size __ecp_nistz256_mul_by_2x,.-__ecp_nistz256_mul_by_2x
+___
+ }
+&gen_double("x");
+&gen_add("x");
+&gen_add_affine("x");
+}
+}}}
+
+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
+# CONTEXT *context,DISPATCHER_CONTEXT *disp)
+if ($win64) {
+$rec="%rcx";
+$frame="%rdx";
+$context="%r8";
+$disp="%r9";
+
+$code.=<<___;
+.extern __imp_RtlVirtualUnwind
+
+.type short_handler,\@abi-omnipotent
+.align 16
+short_handler:
+ push %rsi
+ push %rdi
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+ pushfq
+ sub \$64,%rsp
+
+ mov 120($context),%rax # pull context->Rax
+ mov 248($context),%rbx # pull context->Rip
+
+ mov 8($disp),%rsi # disp->ImageBase
+ mov 56($disp),%r11 # disp->HandlerData
+
+ mov 0(%r11),%r10d # HandlerData[0]
+ lea (%rsi,%r10),%r10 # end of prologue label
+ cmp %r10,%rbx # context->Rip<end of prologue label
+ jb .Lcommon_seh_tail
+
+ mov 152($context),%rax # pull context->Rsp
+
+ mov 4(%r11),%r10d # HandlerData[1]
+ lea (%rsi,%r10),%r10 # epilogue label
+ cmp %r10,%rbx # context->Rip>=epilogue label
+ jae .Lcommon_seh_tail
+
+ lea 16(%rax),%rax
+
+ mov -8(%rax),%r12
+ mov -16(%rax),%r13
+ mov %r12,216($context) # restore context->R12
+ mov %r13,224($context) # restore context->R13
+
+ jmp .Lcommon_seh_tail
+.size short_handler,.-short_handler
+
+.type full_handler,\@abi-omnipotent
+.align 16
+full_handler:
+ push %rsi
+ push %rdi
+ push %rbx
+ push %rbp
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+ pushfq
+ sub \$64,%rsp
+
+ mov 120($context),%rax # pull context->Rax
+ mov 248($context),%rbx # pull context->Rip
+
+ mov 8($disp),%rsi # disp->ImageBase
+ mov 56($disp),%r11 # disp->HandlerData
+
+ mov 0(%r11),%r10d # HandlerData[0]
+ lea (%rsi,%r10),%r10 # end of prologue label
+ cmp %r10,%rbx # context->Rip<end of prologue label
+ jb .Lcommon_seh_tail
+
+ mov 152($context),%rax # pull context->Rsp
+
+ mov 4(%r11),%r10d # HandlerData[1]
+ lea (%rsi,%r10),%r10 # epilogue label
+ cmp %r10,%rbx # context->Rip>=epilogue label
+ jae .Lcommon_seh_tail
+
+ mov 8(%r11),%r10d # HandlerData[2]
+ lea (%rax,%r10),%rax
+
+ mov -8(%rax),%rbp
+ mov -16(%rax),%rbx
+ mov -24(%rax),%r12
+ mov -32(%rax),%r13
+ mov -40(%rax),%r14
+ mov -48(%rax),%r15
+ mov %rbx,144($context) # restore context->Rbx
+ mov %rbp,160($context) # restore context->Rbp
+ mov %r12,216($context) # restore context->R12
+ mov %r13,224($context) # restore context->R13
+ mov %r14,232($context) # restore context->R14
+ mov %r15,240($context) # restore context->R15
+
+.Lcommon_seh_tail:
+ mov 8(%rax),%rdi
+ mov 16(%rax),%rsi
+ mov %rax,152($context) # restore context->Rsp
+ mov %rsi,168($context) # restore context->Rsi
+ mov %rdi,176($context) # restore context->Rdi
+
+ mov 40($disp),%rdi # disp->ContextRecord
+ mov $context,%rsi # context
+ mov \$154,%ecx # sizeof(CONTEXT)
+ .long 0xa548f3fc # cld; rep movsq
+
+ mov $disp,%rsi
+ xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER
+ mov 8(%rsi),%rdx # arg2, disp->ImageBase
+ mov 0(%rsi),%r8 # arg3, disp->ControlPc
+ mov 16(%rsi),%r9 # arg4, disp->FunctionEntry
+ mov 40(%rsi),%r10 # disp->ContextRecord
+ lea 56(%rsi),%r11 # &disp->HandlerData
+ lea 24(%rsi),%r12 # &disp->EstablisherFrame
+ mov %r10,32(%rsp) # arg5
+ mov %r11,40(%rsp) # arg6
+ mov %r12,48(%rsp) # arg7
+ mov %rcx,56(%rsp) # arg8, (NULL)
+ call *__imp_RtlVirtualUnwind(%rip)
+
+ mov \$1,%eax # ExceptionContinueSearch
+ add \$64,%rsp
+ popfq
+ pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ pop %rbp
+ pop %rbx
+ pop %rdi
+ pop %rsi
+ ret
+.size full_handler,.-full_handler
+
+.section .pdata
+.align 4
+ .rva .LSEH_begin_ecp_nistz256_neg
+ .rva .LSEH_end_ecp_nistz256_neg
+ .rva .LSEH_info_ecp_nistz256_neg
+
+ .rva .LSEH_begin_ecp_nistz256_ord_mul_mont
+ .rva .LSEH_end_ecp_nistz256_ord_mul_mont
+ .rva .LSEH_info_ecp_nistz256_ord_mul_mont
+
+ .rva .LSEH_begin_ecp_nistz256_ord_sqr_mont
+ .rva .LSEH_end_ecp_nistz256_ord_sqr_mont
+ .rva .LSEH_info_ecp_nistz256_ord_sqr_mont
+___
+$code.=<<___ if ($addx);
+ .rva .LSEH_begin_ecp_nistz256_ord_mul_montx
+ .rva .LSEH_end_ecp_nistz256_ord_mul_montx
+ .rva .LSEH_info_ecp_nistz256_ord_mul_montx
+
+ .rva .LSEH_begin_ecp_nistz256_ord_sqr_montx
+ .rva .LSEH_end_ecp_nistz256_ord_sqr_montx
+ .rva .LSEH_info_ecp_nistz256_ord_sqr_montx
+___
+$code.=<<___;
+ .rva .LSEH_begin_ecp_nistz256_mul_mont
+ .rva .LSEH_end_ecp_nistz256_mul_mont
+ .rva .LSEH_info_ecp_nistz256_mul_mont
+
+ .rva .LSEH_begin_ecp_nistz256_sqr_mont
+ .rva .LSEH_end_ecp_nistz256_sqr_mont
+ .rva .LSEH_info_ecp_nistz256_sqr_mont
+
+ .rva .LSEH_begin_ecp_nistz256_select_w5
+ .rva .LSEH_end_ecp_nistz256_select_w5
+ .rva .LSEH_info_ecp_nistz256_select_wX
+
+ .rva .LSEH_begin_ecp_nistz256_select_w7
+ .rva .LSEH_end_ecp_nistz256_select_w7
+ .rva .LSEH_info_ecp_nistz256_select_wX
+___
+$code.=<<___ if ($avx>1);
+ .rva .LSEH_begin_ecp_nistz256_avx2_select_w5
+ .rva .LSEH_end_ecp_nistz256_avx2_select_w5
+ .rva .LSEH_info_ecp_nistz256_avx2_select_wX
+
+ .rva .LSEH_begin_ecp_nistz256_avx2_select_w7
+ .rva .LSEH_end_ecp_nistz256_avx2_select_w7
+ .rva .LSEH_info_ecp_nistz256_avx2_select_wX
+___
+$code.=<<___;
+ .rva .LSEH_begin_ecp_nistz256_point_double
+ .rva .LSEH_end_ecp_nistz256_point_double
+ .rva .LSEH_info_ecp_nistz256_point_double
+
+ .rva .LSEH_begin_ecp_nistz256_point_add
+ .rva .LSEH_end_ecp_nistz256_point_add
+ .rva .LSEH_info_ecp_nistz256_point_add
+
+ .rva .LSEH_begin_ecp_nistz256_point_add_affine
+ .rva .LSEH_end_ecp_nistz256_point_add_affine
+ .rva .LSEH_info_ecp_nistz256_point_add_affine
+___
+$code.=<<___ if ($addx);
+ .rva .LSEH_begin_ecp_nistz256_point_doublex
+ .rva .LSEH_end_ecp_nistz256_point_doublex
+ .rva .LSEH_info_ecp_nistz256_point_doublex
+
+ .rva .LSEH_begin_ecp_nistz256_point_addx
+ .rva .LSEH_end_ecp_nistz256_point_addx
+ .rva .LSEH_info_ecp_nistz256_point_addx
+
+ .rva .LSEH_begin_ecp_nistz256_point_add_affinex
+ .rva .LSEH_end_ecp_nistz256_point_add_affinex
+ .rva .LSEH_info_ecp_nistz256_point_add_affinex
+___
+$code.=<<___;
+
+.section .xdata
+.align 8
+.LSEH_info_ecp_nistz256_neg:
+ .byte 9,0,0,0
+ .rva short_handler
+ .rva .Lneg_body,.Lneg_epilogue # HandlerData[]
+.LSEH_info_ecp_nistz256_ord_mul_mont:
+ .byte 9,0,0,0
+ .rva full_handler
+ .rva .Lord_mul_body,.Lord_mul_epilogue # HandlerData[]
+ .long 48,0
+.LSEH_info_ecp_nistz256_ord_sqr_mont:
+ .byte 9,0,0,0
+ .rva full_handler
+ .rva .Lord_sqr_body,.Lord_sqr_epilogue # HandlerData[]
+ .long 48,0
+___
+$code.=<<___ if ($addx);
+.LSEH_info_ecp_nistz256_ord_mul_montx:
+ .byte 9,0,0,0
+ .rva full_handler
+ .rva .Lord_mulx_body,.Lord_mulx_epilogue # HandlerData[]
+ .long 48,0
+.LSEH_info_ecp_nistz256_ord_sqr_montx:
+ .byte 9,0,0,0
+ .rva full_handler
+ .rva .Lord_sqrx_body,.Lord_sqrx_epilogue # HandlerData[]
+ .long 48,0
+___
+$code.=<<___;
+.LSEH_info_ecp_nistz256_mul_mont:
+ .byte 9,0,0,0
+ .rva full_handler
+ .rva .Lmul_body,.Lmul_epilogue # HandlerData[]
+ .long 48,0
+.LSEH_info_ecp_nistz256_sqr_mont:
+ .byte 9,0,0,0
+ .rva full_handler
+ .rva .Lsqr_body,.Lsqr_epilogue # HandlerData[]
+ .long 48,0
+.LSEH_info_ecp_nistz256_select_wX:
+ .byte 0x01,0x33,0x16,0x00
+ .byte 0x33,0xf8,0x09,0x00 #movaps 0x90(rsp),xmm15
+ .byte 0x2e,0xe8,0x08,0x00 #movaps 0x80(rsp),xmm14
+ .byte 0x29,0xd8,0x07,0x00 #movaps 0x70(rsp),xmm13
+ .byte 0x24,0xc8,0x06,0x00 #movaps 0x60(rsp),xmm12
+ .byte 0x1f,0xb8,0x05,0x00 #movaps 0x50(rsp),xmm11
+ .byte 0x1a,0xa8,0x04,0x00 #movaps 0x40(rsp),xmm10
+ .byte 0x15,0x98,0x03,0x00 #movaps 0x30(rsp),xmm9
+ .byte 0x10,0x88,0x02,0x00 #movaps 0x20(rsp),xmm8
+ .byte 0x0c,0x78,0x01,0x00 #movaps 0x10(rsp),xmm7
+ .byte 0x08,0x68,0x00,0x00 #movaps 0x00(rsp),xmm6
+ .byte 0x04,0x01,0x15,0x00 #sub rsp,0xa8
+ .align 8
+___
+$code.=<<___ if ($avx>1);
+.LSEH_info_ecp_nistz256_avx2_select_wX:
+ .byte 0x01,0x36,0x17,0x0b
+ .byte 0x36,0xf8,0x09,0x00 # vmovaps 0x90(rsp),xmm15
+ .byte 0x31,0xe8,0x08,0x00 # vmovaps 0x80(rsp),xmm14
+ .byte 0x2c,0xd8,0x07,0x00 # vmovaps 0x70(rsp),xmm13
+ .byte 0x27,0xc8,0x06,0x00 # vmovaps 0x60(rsp),xmm12
+ .byte 0x22,0xb8,0x05,0x00 # vmovaps 0x50(rsp),xmm11
+ .byte 0x1d,0xa8,0x04,0x00 # vmovaps 0x40(rsp),xmm10
+ .byte 0x18,0x98,0x03,0x00 # vmovaps 0x30(rsp),xmm9
+ .byte 0x13,0x88,0x02,0x00 # vmovaps 0x20(rsp),xmm8
+ .byte 0x0e,0x78,0x01,0x00 # vmovaps 0x10(rsp),xmm7
+ .byte 0x09,0x68,0x00,0x00 # vmovaps 0x00(rsp),xmm6
+ .byte 0x04,0x01,0x15,0x00 # sub rsp,0xa8
+ .byte 0x00,0xb3,0x00,0x00 # set_frame r11
+ .align 8
+___
+$code.=<<___;
+.LSEH_info_ecp_nistz256_point_double:
+ .byte 9,0,0,0
+ .rva full_handler
+ .rva .Lpoint_doubleq_body,.Lpoint_doubleq_epilogue # HandlerData[]
+ .long 32*5+56,0
+.LSEH_info_ecp_nistz256_point_add:
+ .byte 9,0,0,0
+ .rva full_handler
+ .rva .Lpoint_addq_body,.Lpoint_addq_epilogue # HandlerData[]
+ .long 32*18+56,0
+.LSEH_info_ecp_nistz256_point_add_affine:
+ .byte 9,0,0,0
+ .rva full_handler
+ .rva .Ladd_affineq_body,.Ladd_affineq_epilogue # HandlerData[]
+ .long 32*15+56,0
+___
+$code.=<<___ if ($addx);
+.align 8
+.LSEH_info_ecp_nistz256_point_doublex:
+ .byte 9,0,0,0
+ .rva full_handler
+ .rva .Lpoint_doublex_body,.Lpoint_doublex_epilogue # HandlerData[]
+ .long 32*5+56,0
+.LSEH_info_ecp_nistz256_point_addx:
+ .byte 9,0,0,0
+ .rva full_handler
+ .rva .Lpoint_addx_body,.Lpoint_addx_epilogue # HandlerData[]
+ .long 32*18+56,0
+.LSEH_info_ecp_nistz256_point_add_affinex:
+ .byte 9,0,0,0
+ .rva full_handler
+ .rva .Ladd_affinex_body,.Ladd_affinex_epilogue # HandlerData[]
+ .long 32*15+56,0
+___
+}
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+print $code;
+close STDOUT or die "error closing STDOUT: $!";
diff --git a/src/crypto/fipsmodule/ec/asm/p256_beeu-armv8-asm.pl b/src/crypto/fipsmodule/ec/asm/p256_beeu-armv8-asm.pl
new file mode 100644
index 0000000..e259aef
--- /dev/null
+++ b/src/crypto/fipsmodule/ec/asm/p256_beeu-armv8-asm.pl
@@ -0,0 +1,455 @@
+# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+#
+#
+# This code is based on p256_beeu-x86_64-asm.pl (which is based on BN_mod_inverse_odd).
+#
+
+# The first two arguments should always be the flavour and output file path.
+if ($#ARGV < 1) { die "Not enough arguments provided.
+ Two arguments are necessary: the flavour and the output file path."; }
+
+$flavour = shift;
+$output = shift;
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../../perlasm/arm-xlate.pl" and -f $xlate) or
+die "can't locate arm-xlate.pl";
+
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
+#############################################################################
+# extern int beeu_mod_inverse_vartime(BN_ULONG out[P256_LIMBS],
+# BN_ULONG a[P256_LIMBS],
+# BN_ULONG n[P256_LIMBS]);
+#
+# (Binary Extended GCD (Euclidean) Algorithm.
+# See A. Menezes, P. vanOorschot, and S. Vanstone's Handbook of Applied Cryptography,
+# Chapter 14, Algorithm 14.61 and Note 14.64
+# http://cacr.uwaterloo.ca/hac/about/chap14.pdf)
+
+# Assumption 1: n is odd for the BEEU
+# Assumption 2: 1 < a < n < 2^256
+
+# Details
+# The inverse of x modulo y can be calculated using Alg. 14.61, where "a" would be that inverse.
+# In other words,
+# ax == 1 (mod y) (where the symbol “==“ denotes ”congruent“)
+# a == x^{-1} (mod y)
+#
+# It can be shown that throughout all the iterations of the algorithm, the following holds:
+# u = Ax + By
+# v = Cx + Dy
+# The values B and D are not of interest in this case, so they need not be computed by the algorithm.
+# This means the following congruences hold through the iterations of the algorithm.
+# Ax == u (mod y)
+# Cx == v (mod y)
+
+# Now we will modify the notation to match that of BN_mod_inverse_odd()
+# on which beeu_mod_inverse_vartime() in `p256_beeu-x86_64-asm` is based.
+# In those functions:
+# x, y -> a, n
+# u, v -> B, A
+# A, C -> X, Y’, where Y’ = -Y
+# Hence, the following holds throughout the algorithm iterations
+# Xa == B (mod n)
+# -Ya == A (mod n)
+#
+# Same algorithm in Python:
+# def beeu(a, n):
+# X = 1
+# Y = 0
+# B = a
+# A = n
+# while (B != 0):
+# while (B % 2) == 0:
+# B >>= 1
+# if (X % 2) == 1:
+# X = X + n
+# X >>= 1
+# while (A % 2) == 0:
+# A >>= 1
+# if (Y % 2) == 1:
+# Y = Y + n
+# Y >>= 1
+# if (B >= A):
+# B = B - A
+# X = X + Y
+# else:
+# A = A - B
+# Y = Y + X
+# if (A != 1):
+# # error
+# return 0
+# else:
+# while (Y > n):
+# Y = Y - n
+# Y = n - Y
+# return Y
+
+
+# For the internal variables,
+# x0-x2, x30 are used to hold the modulus n. The input parameters passed in
+# x1,x2 are copied first before corrupting them. x0 (out) is stored on the stack.
+# x3-x7 are used for parameters, which is not the case in this function, so they are corruptible
+# x8 is corruptible here
+# (the function doesn't return a struct, hence x8 doesn't contain a passed-in address
+# for that struct).
+# x9-x15 are corruptible registers
+# x19-x28 are callee-saved registers
+
+# X/Y will hold the inverse parameter
+# Assumption: a,n,X,Y < 2^(256)
+# Initially, X := 1, Y := 0
+# A := n, B := a
+
+# Function parameters (as per the Procedure Call Standard)
+my($out, $a_in, $n_in)=map("x$_",(0..2));
+# Internal variables
+my($n0, $n1, $n2, $n3)=map("x$_",(0..2,30));
+my($x0, $x1, $x2, $x3, $x4)=map("x$_",(3..7));
+my($y0, $y1, $y2, $y3, $y4)=map("x$_",(8..12));
+my($shift)=("x13");
+my($t0, $t1, $t2, $t3)=map("x$_",(14,15,19,20));
+my($a0, $a1, $a2, $a3)=map("x$_",(21..24));
+my($b0, $b1, $b2, $b3)=map("x$_",(25..28));
+
+# if B == 0, jump to end of loop
+sub TEST_B_ZERO {
+ return <<___;
+ orr $t0, $b0, $b1
+ orr $t0, $t0, $b2
+
+ // reverse the bit order of $b0. This is needed for clz after this macro
+ rbit $t1, $b0
+
+ orr $t0, $t0, $b3
+ cbz $t0,.Lbeeu_loop_end
+___
+}
+
+# Shift right by 1 bit, adding the modulus first if the variable is odd
+# if least_sig_bit(var0) == 0,
+# goto shift1_<ctr>
+# else
+# add n and goto shift1_<ctr>
+# Prerequisite: t0 = 0
+$g_next_label = 0;
+sub SHIFT1 {
+ my ($var0, $var1, $var2, $var3, $var4) = @_;
+ my $label = ".Lshift1_${g_next_label}";
+ $g_next_label++;
+ return <<___;
+ tbz $var0, #0, $label
+ adds $var0, $var0, $n0
+ adcs $var1, $var1, $n1
+ adcs $var2, $var2, $n2
+ adcs $var3, $var3, $n3
+ adc $var4, $var4, $t0
+$label:
+ // var0 := [var1|var0]<64..1>;
+ // i.e. concatenate var1 and var0,
+ // extract bits <64..1> from the resulting 128-bit value
+ // and put them in var0
+ extr $var0, $var1, $var0, #1
+ extr $var1, $var2, $var1, #1
+ extr $var2, $var3, $var2, #1
+ extr $var3, $var4, $var3, #1
+ lsr $var4, $var4, #1
+___
+}
+
+# compilation by clang 10.0.0 with -O2/-O3 of
+# a[0] = (a[0] >> count) | (a[1] << (64-count));
+# a[1] = (a[1] >> count) | (a[2] << (64-count));
+# a[2] = (a[2] >> count) | (a[3] << (64-count));
+# a[3] >>= count;
+# Note: EXTR instruction used in SHIFT1 is similar to x86_64's SHRDQ
+# except that the second source operand of EXTR is only immediate;
+# that's why it cannot be used here where $shift is a variable
+#
+# In the following,
+# t0 := 0 - shift
+#
+# then var0, for example, will be shifted right as follows:
+# var0 := (var0 >> (uint(shift) mod 64)) | (var1 << (uint(t0) mod 64))
+# "uint() mod 64" is from the definition of LSL and LSR instructions.
+#
+# What matters here is the order of instructions relative to certain other
+# instructions, i.e.
+# - lsr and lsl must precede orr of the corresponding registers.
+# - lsl must preced the lsr of the same register afterwards.
+# The chosen order of the instructions overall is to try and maximize
+# the pipeline usage.
+sub SHIFT256 {
+ my ($var0, $var1, $var2, $var3) = @_;
+ return <<___;
+ neg $t0, $shift
+ lsr $var0, $var0, $shift
+ lsl $t1, $var1, $t0
+
+ lsr $var1, $var1, $shift
+ lsl $t2, $var2, $t0
+
+ orr $var0, $var0, $t1
+
+ lsr $var2, $var2, $shift
+ lsl $t3, $var3, $t0
+
+ orr $var1, $var1, $t2
+
+ lsr $var3, $var3, $shift
+
+ orr $var2, $var2, $t3
+___
+}
+
+$code.=<<___;
+#include "openssl/arm_arch.h"
+
+.text
+.globl beeu_mod_inverse_vartime
+.type beeu_mod_inverse_vartime, %function
+.align 4
+beeu_mod_inverse_vartime:
+ // Reserve enough space for 14 8-byte registers on the stack
+ // in the first stp call for x29, x30.
+ // Then store the remaining callee-saved registers.
+ //
+ // | x29 | x30 | x19 | x20 | ... | x27 | x28 | x0 | x2 |
+ // ^ ^
+ // sp <------------------- 112 bytes ----------------> old sp
+ // x29 (FP)
+ //
+ AARCH64_SIGN_LINK_REGISTER
+ stp x29,x30,[sp,#-112]!
+ add x29,sp,#0
+ stp x19,x20,[sp,#16]
+ stp x21,x22,[sp,#32]
+ stp x23,x24,[sp,#48]
+ stp x25,x26,[sp,#64]
+ stp x27,x28,[sp,#80]
+ stp x0,x2,[sp,#96]
+
+ // B = b3..b0 := a
+ ldp $b0,$b1,[$a_in]
+ ldp $b2,$b3,[$a_in,#16]
+
+ // n3..n0 := n
+ // Note: the value of input params are changed in the following.
+ ldp $n0,$n1,[$n_in]
+ ldp $n2,$n3,[$n_in,#16]
+
+ // A = a3..a0 := n
+ mov $a0, $n0
+ mov $a1, $n1
+ mov $a2, $n2
+ mov $a3, $n3
+
+ // X = x4..x0 := 1
+ mov $x0, #1
+ eor $x1, $x1, $x1
+ eor $x2, $x2, $x2
+ eor $x3, $x3, $x3
+ eor $x4, $x4, $x4
+
+ // Y = y4..y0 := 0
+ eor $y0, $y0, $y0
+ eor $y1, $y1, $y1
+ eor $y2, $y2, $y2
+ eor $y3, $y3, $y3
+ eor $y4, $y4, $y4
+
+.Lbeeu_loop:
+ // if B == 0, jump to .Lbeeu_loop_end
+ ${\TEST_B_ZERO}
+
+ // 0 < B < |n|,
+ // 0 < A <= |n|,
+ // (1) X*a == B (mod |n|),
+ // (2) (-1)*Y*a == A (mod |n|)
+
+ // Now divide B by the maximum possible power of two in the
+ // integers, and divide X by the same value mod |n|.
+ // When we're done, (1) still holds.
+
+ // shift := number of trailing 0s in $b0
+ // ( = number of leading 0s in $t1; see the "rbit" instruction in TEST_B_ZERO)
+ clz $shift, $t1
+
+ // If there is no shift, goto shift_A_Y
+ cbz $shift, .Lbeeu_shift_A_Y
+
+ // Shift B right by "$shift" bits
+ ${\SHIFT256($b0, $b1, $b2, $b3)}
+
+ // Shift X right by "$shift" bits, adding n whenever X becomes odd.
+ // $shift--;
+ // $t0 := 0; needed in the addition to the most significant word in SHIFT1
+ eor $t0, $t0, $t0
+.Lbeeu_shift_loop_X:
+ ${\SHIFT1($x0, $x1, $x2, $x3, $x4)}
+ subs $shift, $shift, #1
+ bne .Lbeeu_shift_loop_X
+
+ // Note: the steps above perform the same sequence as in p256_beeu-x86_64-asm.pl
+ // with the following differences:
+ // - "$shift" is set directly to the number of trailing 0s in B
+ // (using rbit and clz instructions)
+ // - The loop is only used to call SHIFT1(X)
+ // and $shift is decreased while executing the X loop.
+ // - SHIFT256(B, $shift) is performed before right-shifting X; they are independent
+
+.Lbeeu_shift_A_Y:
+ // Same for A and Y.
+ // Afterwards, (2) still holds.
+ // Reverse the bit order of $a0
+ // $shift := number of trailing 0s in $a0 (= number of leading 0s in $t1)
+ rbit $t1, $a0
+ clz $shift, $t1
+
+ // If there is no shift, goto |B-A|, X+Y update
+ cbz $shift, .Lbeeu_update_B_X_or_A_Y
+
+ // Shift A right by "$shift" bits
+ ${\SHIFT256($a0, $a1, $a2, $a3)}
+
+ // Shift Y right by "$shift" bits, adding n whenever Y becomes odd.
+ // $shift--;
+ // $t0 := 0; needed in the addition to the most significant word in SHIFT1
+ eor $t0, $t0, $t0
+.Lbeeu_shift_loop_Y:
+ ${\SHIFT1($y0, $y1, $y2, $y3, $y4)}
+ subs $shift, $shift, #1
+ bne .Lbeeu_shift_loop_Y
+
+.Lbeeu_update_B_X_or_A_Y:
+ // Try T := B - A; if cs, continue with B > A (cs: carry set = no borrow)
+ // Note: this is a case of unsigned arithmetic, where T fits in 4 64-bit words
+ // without taking a sign bit if generated. The lack of a carry would
+ // indicate a negative result. See, for example,
+ // https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/condition-codes-1-condition-flags-and-codes
+ subs $t0, $b0, $a0
+ sbcs $t1, $b1, $a1
+ sbcs $t2, $b2, $a2
+ sbcs $t3, $b3, $a3
+ bcs .Lbeeu_B_greater_than_A
+
+ // Else A > B =>
+ // A := A - B; Y := Y + X; goto beginning of the loop
+ subs $a0, $a0, $b0
+ sbcs $a1, $a1, $b1
+ sbcs $a2, $a2, $b2
+ sbcs $a3, $a3, $b3
+
+ adds $y0, $y0, $x0
+ adcs $y1, $y1, $x1
+ adcs $y2, $y2, $x2
+ adcs $y3, $y3, $x3
+ adc $y4, $y4, $x4
+ b .Lbeeu_loop
+
+.Lbeeu_B_greater_than_A:
+ // Continue with B > A =>
+ // B := B - A; X := X + Y; goto beginning of the loop
+ mov $b0, $t0
+ mov $b1, $t1
+ mov $b2, $t2
+ mov $b3, $t3
+
+ adds $x0, $x0, $y0
+ adcs $x1, $x1, $y1
+ adcs $x2, $x2, $y2
+ adcs $x3, $x3, $y3
+ adc $x4, $x4, $y4
+ b .Lbeeu_loop
+
+.Lbeeu_loop_end:
+ // The Euclid's algorithm loop ends when A == gcd(a,n);
+ // this would be 1, when a and n are co-prime (i.e. do not have a common factor).
+ // Since (-1)*Y*a == A (mod |n|), Y>0
+ // then out = -Y mod n
+
+ // Verify that A = 1 ==> (-1)*Y*a = A = 1 (mod |n|)
+ // Is A-1 == 0?
+ // If not, fail.
+ sub $t0, $a0, #1
+ orr $t0, $t0, $a1
+ orr $t0, $t0, $a2
+ orr $t0, $t0, $a3
+ cbnz $t0, .Lbeeu_err
+
+ // If Y>n ==> Y:=Y-n
+.Lbeeu_reduction_loop:
+ // x_i := y_i - n_i (X is no longer needed, use it as temp)
+ // ($t0 = 0 from above)
+ subs $x0, $y0, $n0
+ sbcs $x1, $y1, $n1
+ sbcs $x2, $y2, $n2
+ sbcs $x3, $y3, $n3
+ sbcs $x4, $y4, $t0
+
+ // If result is non-negative (i.e., cs = carry set = no borrow),
+ // y_i := x_i; goto reduce again
+ // else
+ // y_i := y_i; continue
+ csel $y0, $x0, $y0, cs
+ csel $y1, $x1, $y1, cs
+ csel $y2, $x2, $y2, cs
+ csel $y3, $x3, $y3, cs
+ csel $y4, $x4, $y4, cs
+ bcs .Lbeeu_reduction_loop
+
+ // Now Y < n (Y cannot be equal to n, since the inverse cannot be 0)
+ // out = -Y = n-Y
+ subs $y0, $n0, $y0
+ sbcs $y1, $n1, $y1
+ sbcs $y2, $n2, $y2
+ sbcs $y3, $n3, $y3
+
+ // Save Y in output (out (x0) was saved on the stack)
+ ldr x3, [sp,#96]
+ stp $y0, $y1, [x3]
+ stp $y2, $y3, [x3,#16]
+ // return 1 (success)
+ mov x0, #1
+ b .Lbeeu_finish
+
+.Lbeeu_err:
+ // return 0 (error)
+ eor x0, x0, x0
+
+.Lbeeu_finish:
+ // Restore callee-saved registers, except x0, x2
+ add sp,x29,#0
+ ldp x19,x20,[sp,#16]
+ ldp x21,x22,[sp,#32]
+ ldp x23,x24,[sp,#48]
+ ldp x25,x26,[sp,#64]
+ ldp x27,x28,[sp,#80]
+ ldp x29,x30,[sp],#112
+
+ AARCH64_VALIDATE_LINK_REGISTER
+ ret
+.size beeu_mod_inverse_vartime,.-beeu_mod_inverse_vartime
+___
+
+
+foreach (split("\n",$code)) {
+ s/\`([^\`]*)\`/eval $1/ge;
+
+ print $_,"\n";
+}
+close STDOUT or die "error closing STDOUT: $!"; # enforce flush
diff --git a/src/crypto/fipsmodule/ec/asm/p256_beeu-x86_64-asm.pl b/src/crypto/fipsmodule/ec/asm/p256_beeu-x86_64-asm.pl
new file mode 100644
index 0000000..b9ec96d
--- /dev/null
+++ b/src/crypto/fipsmodule/ec/asm/p256_beeu-x86_64-asm.pl
@@ -0,0 +1,403 @@
+# Copyright (c) 2018, Amazon Inc.
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+#
+# Written by Nir Drucker, and Shay Gueron
+# AWS Cryptographic Algorithms Group
+# (ndrucker@amazon.com, gueron@amazon.com)
+# based on BN_mod_inverse_odd
+
+$flavour = shift;
+$output = shift;
+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
+
+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../../perlasm/x86_64-xlate.pl" and -f $xlate) or
+die "can't locate x86_64-xlate.pl";
+
+open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"";
+*STDOUT=*OUT;
+
+#############################################################################
+# extern int beeu_mod_inverse_vartime(BN_ULONG out[P256_LIMBS],
+# BN_ULONG a[P256_LIMBS],
+# BN_ULONG n[P256_LIMBS]);
+#
+# (Binary Extended Euclidean Algorithm.
+# See https://en.wikipedia.org/wiki/Binary_GCD_algorithm)
+#
+# Assumption 1: n is odd for the BEEU
+# Assumption 2: 1 < a < n < 2^256
+
+$out = "%rdi";
+$a = "%rsi";
+$n = "%rdx";
+
+# X/Y will hold the inverse parameter
+# Assumption: X,Y<2^(256)
+$x0 = "%r8";
+$x1 = "%r9";
+$x2 = "%r10";
+$x3 = "%r11";
+# borrow from out (out is needed only at the end)
+$x4 = "%rdi";
+$y0 = "%r12";
+$y1 = "%r13";
+$y2 = "%r14";
+$y3 = "%r15";
+$y4 = "%rbp";
+$shift = "%rcx";
+$t0 = "%rax";
+$t1 = "%rbx";
+$t2 = "%rsi";
+# borrow
+$t3 = "%rcx";
+
+$T0 = "%xmm0";
+$T1 = "%xmm1";
+
+# Offsets on the stack
+$out_rsp = 0;
+$shift_rsp = $out_rsp+0x8;
+$a_rsp0 = $shift_rsp+0x8;
+$a_rsp1 = $a_rsp0+0x8;
+$a_rsp2 = $a_rsp1+0x8;
+$a_rsp3 = $a_rsp2+0x8;
+$b_rsp0 = $a_rsp3+0x8;
+$b_rsp1 = $b_rsp0+0x8;
+$b_rsp2 = $b_rsp1+0x8;
+$b_rsp3 = $b_rsp2+0x8;
+
+# Borrow when a_rsp/b_rsp are no longer needed.
+$y_rsp0 = $a_rsp0;
+$y_rsp1 = $y_rsp0+0x8;
+$y_rsp2 = $y_rsp1+0x8;
+$y_rsp3 = $y_rsp2+0x8;
+$y_rsp4 = $y_rsp3+0x8;
+$last_rsp_offset = $b_rsp3+0x8;
+
+sub TEST_B_ZERO {
+ return <<___;
+ xorq $t1, $t1
+ or $b_rsp0(%rsp), $t1
+ or $b_rsp1(%rsp), $t1
+ or $b_rsp2(%rsp), $t1
+ or $b_rsp3(%rsp), $t1
+ jz .Lbeeu_loop_end
+___
+}
+
+$g_next_label = 0;
+
+sub SHIFT1 {
+ my ($var0, $var1, $var2, $var3, $var4) = @_;
+ my $label = ".Lshift1_${g_next_label}";
+ $g_next_label++;
+
+ return <<___;
+ # Ensure X is even and divide by two.
+ movq \$1, $t1
+ andq $var0, $t1
+ jz $label
+ add 0*8($n), $var0
+ adc 1*8($n), $var1
+ adc 2*8($n), $var2
+ adc 3*8($n), $var3
+ adc \$0, $var4
+
+$label:
+ shrdq \$1, $var1, $var0
+ shrdq \$1, $var2, $var1
+ shrdq \$1, $var3, $var2
+ shrdq \$1, $var4, $var3
+ shrq \$1, $var4
+___
+}
+
+sub SHIFT256 {
+ my ($var) = @_;
+ return <<___;
+ # Copy shifted values.
+ # Remember not to override t3=rcx
+ movq 1*8+$var(%rsp), $t0
+ movq 2*8+$var(%rsp), $t1
+ movq 3*8+$var(%rsp), $t2
+
+ shrdq %cl, $t0, 0*8+$var(%rsp)
+ shrdq %cl, $t1, 1*8+$var(%rsp)
+ shrdq %cl, $t2, 2*8+$var(%rsp)
+
+ shrq %cl, $t2
+ mov $t2, 3*8+$var(%rsp)
+___
+}
+
+$code.=<<___;
+.text
+
+.type beeu_mod_inverse_vartime,\@function
+.hidden beeu_mod_inverse_vartime
+.globl beeu_mod_inverse_vartime
+.align 32
+beeu_mod_inverse_vartime:
+.cfi_startproc
+ push %rbp
+.cfi_push rbp
+ push %r12
+.cfi_push r12
+ push %r13
+.cfi_push r13
+ push %r14
+.cfi_push r14
+ push %r15
+.cfi_push r15
+ push %rbx
+.cfi_push rbx
+ push %rsi
+.cfi_push rsi
+
+ sub \$$last_rsp_offset, %rsp
+.cfi_adjust_cfa_offset $last_rsp_offset
+ movq $out, $out_rsp(%rsp)
+
+ # X=1, Y=0
+ movq \$1, $x0
+ xorq $x1, $x1
+ xorq $x2, $x2
+ xorq $x3, $x3
+ xorq $x4, $x4
+
+ xorq $y0, $y0
+ xorq $y1, $y1
+ xorq $y2, $y2
+ xorq $y3, $y3
+ xorq $y4, $y4
+
+ # Copy a/n into B/A on the stack.
+ vmovdqu 0*8($a), $T0
+ vmovdqu 2*8($a), $T1
+ vmovdqu $T0, $b_rsp0(%rsp)
+ vmovdqu $T1, $b_rsp2(%rsp)
+
+ vmovdqu 0*8($n), $T0
+ vmovdqu 2*8($n), $T1
+ vmovdqu $T0, $a_rsp0(%rsp)
+ vmovdqu $T1, $a_rsp2(%rsp)
+
+.Lbeeu_loop:
+ ${\TEST_B_ZERO}
+
+ # 0 < B < |n|,
+ # 0 < A <= |n|,
+ # (1) X*a == B (mod |n|),
+ # (2) (-1)*Y*a == A (mod |n|)
+
+ # Now divide B by the maximum possible power of two in the
+ # integers, and divide X by the same value mod |n|. When we're
+ # done, (1) still holds.
+ movq \$1, $shift
+
+ # Note that B > 0
+.Lbeeu_shift_loop_XB:
+ movq $shift, $t1
+ andq $b_rsp0(%rsp), $t1
+ jnz .Lbeeu_shift_loop_end_XB
+
+ ${\SHIFT1($x0, $x1, $x2, $x3, $x4)}
+ shl \$1, $shift
+
+ # Test wraparound of the shift parameter. The probability to have 32 zeroes
+ # in a row is small Therefore having the value below equal \$0x8000000 or
+ # \$0x8000 does not affect the performance. We choose 0x8000000 because it
+ # is the maximal immediate value possible.
+ cmp \$0x8000000, $shift
+ jne .Lbeeu_shift_loop_XB
+
+.Lbeeu_shift_loop_end_XB:
+ bsf $shift, $shift
+ test $shift, $shift
+ jz .Lbeeu_no_shift_XB
+
+ ${\SHIFT256($b_rsp0)}
+
+.Lbeeu_no_shift_XB:
+ # Same for A and Y. Afterwards, (2) still holds.
+ movq \$1, $shift
+
+ # Note that A > 0
+.Lbeeu_shift_loop_YA:
+ movq $shift, $t1
+ andq $a_rsp0(%rsp), $t1
+ jnz .Lbeeu_shift_loop_end_YA
+
+ ${\SHIFT1($y0, $y1, $y2, $y3, $y4)}
+ shl \$1, $shift
+
+ # Test wraparound of the shift parameter. The probability to have 32 zeroes
+ # in a row is small therefore having the value below equal \$0x8000000 or
+ # \$0x8000 Does not affect the performance. We choose 0x8000000 because it
+ # is the maximal immediate value possible.
+ cmp \$0x8000000, $shift
+ jne .Lbeeu_shift_loop_YA
+
+.Lbeeu_shift_loop_end_YA:
+ bsf $shift, $shift
+ test $shift, $shift
+ jz .Lbeeu_no_shift_YA
+
+ ${\SHIFT256($a_rsp0)}
+
+.Lbeeu_no_shift_YA:
+ # T = B-A (A,B < 2^256)
+ mov $b_rsp0(%rsp), $t0
+ mov $b_rsp1(%rsp), $t1
+ mov $b_rsp2(%rsp), $t2
+ mov $b_rsp3(%rsp), $t3
+ sub $a_rsp0(%rsp), $t0
+ sbb $a_rsp1(%rsp), $t1
+ sbb $a_rsp2(%rsp), $t2
+ sbb $a_rsp3(%rsp), $t3 # borrow from shift
+ jnc .Lbeeu_B_bigger_than_A
+
+ # A = A - B
+ mov $a_rsp0(%rsp), $t0
+ mov $a_rsp1(%rsp), $t1
+ mov $a_rsp2(%rsp), $t2
+ mov $a_rsp3(%rsp), $t3
+ sub $b_rsp0(%rsp), $t0
+ sbb $b_rsp1(%rsp), $t1
+ sbb $b_rsp2(%rsp), $t2
+ sbb $b_rsp3(%rsp), $t3
+ mov $t0, $a_rsp0(%rsp)
+ mov $t1, $a_rsp1(%rsp)
+ mov $t2, $a_rsp2(%rsp)
+ mov $t3, $a_rsp3(%rsp)
+
+ # Y = Y + X
+ add $x0, $y0
+ adc $x1, $y1
+ adc $x2, $y2
+ adc $x3, $y3
+ adc $x4, $y4
+ jmp .Lbeeu_loop
+
+.Lbeeu_B_bigger_than_A:
+ # B = T = B - A
+ mov $t0, $b_rsp0(%rsp)
+ mov $t1, $b_rsp1(%rsp)
+ mov $t2, $b_rsp2(%rsp)
+ mov $t3, $b_rsp3(%rsp)
+
+ # X = Y + X
+ add $y0, $x0
+ adc $y1, $x1
+ adc $y2, $x2
+ adc $y3, $x3
+ adc $y4, $x4
+
+ jmp .Lbeeu_loop
+
+.Lbeeu_loop_end:
+ # The Euclid's algorithm loop ends when A == beeu(a,n);
+ # Therefore (-1)*Y*a == A (mod |n|), Y>0
+
+ # Verify that A = 1 ==> (-1)*Y*a = A = 1 (mod |n|)
+ mov $a_rsp0(%rsp), $t1
+ sub \$1, $t1
+ or $a_rsp1(%rsp), $t1
+ or $a_rsp2(%rsp), $t1
+ or $a_rsp3(%rsp), $t1
+ # If not, fail.
+ jnz .Lbeeu_err
+
+ # From this point on, we no longer need X
+ # Therefore we use it as a temporary storage.
+ # X = n
+ movq 0*8($n), $x0
+ movq 1*8($n), $x1
+ movq 2*8($n), $x2
+ movq 3*8($n), $x3
+ xorq $x4, $x4
+
+.Lbeeu_reduction_loop:
+ movq $y0, $y_rsp0(%rsp)
+ movq $y1, $y_rsp1(%rsp)
+ movq $y2, $y_rsp2(%rsp)
+ movq $y3, $y_rsp3(%rsp)
+ movq $y4, $y_rsp4(%rsp)
+
+ # If Y>n ==> Y=Y-n
+ sub $x0, $y0
+ sbb $x1, $y1
+ sbb $x2, $y2
+ sbb $x3, $y3
+ sbb \$0, $y4
+
+ # Choose old Y or new Y
+ cmovc $y_rsp0(%rsp), $y0
+ cmovc $y_rsp1(%rsp), $y1
+ cmovc $y_rsp2(%rsp), $y2
+ cmovc $y_rsp3(%rsp), $y3
+ jnc .Lbeeu_reduction_loop
+
+ # X = n - Y (n, Y < 2^256), (Cancel the (-1))
+ sub $y0, $x0
+ sbb $y1, $x1
+ sbb $y2, $x2
+ sbb $y3, $x3
+
+.Lbeeu_save:
+ # Save the inverse(<2^256) to out.
+ mov $out_rsp(%rsp), $out
+
+ movq $x0, 0*8($out)
+ movq $x1, 1*8($out)
+ movq $x2, 2*8($out)
+ movq $x3, 3*8($out)
+
+ # Return 1.
+ movq \$1, %rax
+ jmp .Lbeeu_finish
+
+.Lbeeu_err:
+ # Return 0.
+ xorq %rax, %rax
+
+.Lbeeu_finish:
+ add \$$last_rsp_offset, %rsp
+.cfi_adjust_cfa_offset -$last_rsp_offset
+ pop %rsi
+.cfi_pop rsi
+ pop %rbx
+.cfi_pop rbx
+ pop %r15
+.cfi_pop r15
+ pop %r14
+.cfi_pop r14
+ pop %r13
+.cfi_pop r13
+ pop %r12
+.cfi_pop r12
+ pop %rbp
+.cfi_pop rbp
+ ret
+.cfi_endproc
+
+.size beeu_mod_inverse_vartime, .-beeu_mod_inverse_vartime
+___
+
+print $code;
+close STDOUT or die "error closing STDOUT: $!";
diff --git a/src/crypto/fipsmodule/ec/ec.c b/src/crypto/fipsmodule/ec/ec.c
new file mode 100644
index 0000000..2195d06
--- /dev/null
+++ b/src/crypto/fipsmodule/ec/ec.c
@@ -0,0 +1,1268 @@
+/* Originally written by Bodo Moeller for the OpenSSL project.
+ * ====================================================================
+ * Copyright (c) 1998-2005 The OpenSSL Project. 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.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS 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.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * The elliptic curve binary polynomial software is originally written by
+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems
+ * Laboratories. */
+
+#include <openssl/ec.h>
+
+#include <assert.h>
+#include <string.h>
+
+#include <openssl/bn.h>
+#include <openssl/err.h>
+#include <openssl/mem.h>
+#include <openssl/nid.h>
+
+#include "internal.h"
+#include "../../internal.h"
+#include "../bn/internal.h"
+#include "../delocate.h"
+
+
+static void ec_point_free(EC_POINT *point, int free_group);
+
+static const uint8_t kP224Params[6 * 28] = {
+ // p = 2^224 - 2^96 + 1
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01,
+ // a
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFE,
+ // b
+ 0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, 0x32, 0x56,
+ 0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA, 0x27, 0x0B, 0x39, 0x43,
+ 0x23, 0x55, 0xFF, 0xB4,
+ // x
+ 0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, 0x90, 0xB9,
+ 0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xD6,
+ 0x11, 0x5C, 0x1D, 0x21,
+ // y
+ 0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, 0xdf, 0xe6,
+ 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64, 0x44, 0xd5, 0x81, 0x99,
+ 0x85, 0x00, 0x7e, 0x34,
+ // order
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x16, 0xA2, 0xE0, 0xB8, 0xF0, 0x3E, 0x13, 0xDD, 0x29, 0x45,
+ 0x5C, 0x5C, 0x2A, 0x3D,
+};
+
+static const uint8_t kP256Params[6 * 32] = {
+ // p = 2^256 - 2^224 + 2^192 + 2^96 - 1
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ // a
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
+ // b
+ 0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55,
+ 0x76, 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6,
+ 0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B,
+ // x
+ 0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5,
+ 0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0,
+ 0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96,
+ // y
+ 0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a,
+ 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce,
+ 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5,
+ // order
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84,
+ 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51,
+};
+
+static const uint8_t kP384Params[6 * 48] = {
+ // p = 2^384 - 2^128 - 2^96 + 2^32 - 1
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
+ // a
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC,
+ // b
+ 0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, 0x98, 0x8E, 0x05, 0x6B,
+ 0xE3, 0xF8, 0x2D, 0x19, 0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12,
+ 0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A, 0xC6, 0x56, 0x39, 0x8D,
+ 0x8A, 0x2E, 0xD1, 0x9D, 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF,
+ // x
+ 0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x1E,
+ 0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98,
+ 0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, 0x55, 0x02, 0xF2, 0x5D,
+ 0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7,
+ // y
+ 0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f, 0x5d, 0x9e, 0x98, 0xbf,
+ 0x92, 0x92, 0xdc, 0x29, 0xf8, 0xf4, 0x1d, 0xbd, 0x28, 0x9a, 0x14, 0x7c,
+ 0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0, 0xb8, 0xc0, 0x0a, 0x60, 0xb1, 0xce,
+ 0x1d, 0x7e, 0x81, 0x9d, 0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x5f,
+ // order
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF, 0x58, 0x1A, 0x0D, 0xB2,
+ 0x48, 0xB0, 0xA7, 0x7A, 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73,
+};
+
+static const uint8_t kP521Params[6 * 66] = {
+ // p = 2^521 - 1
+ 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ // a
+ 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
+ // b
+ 0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F, 0x92, 0x9A,
+ 0x21, 0xA0, 0xB6, 0x85, 0x40, 0xEE, 0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3,
+ 0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, 0x09, 0xE1, 0x56, 0x19,
+ 0x39, 0x51, 0xEC, 0x7E, 0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1,
+ 0xBF, 0x07, 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1, 0xEF, 0x45,
+ 0x1F, 0xD4, 0x6B, 0x50, 0x3F, 0x00,
+ // x
+ 0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, 0x9E, 0x3E,
+ 0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F,
+ 0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA, 0xA1, 0x4B,
+ 0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF,
+ 0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E,
+ 0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66,
+ // y
+ 0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a,
+ 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b,
+ 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee,
+ 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad,
+ 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe,
+ 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50,
+ // order
+ 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x51, 0x86,
+ 0x87, 0x83, 0xBF, 0x2F, 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09,
+ 0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, 0xBB, 0x6F,
+ 0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09,
+};
+
+DEFINE_METHOD_FUNCTION(struct built_in_curves, OPENSSL_built_in_curves) {
+ // 1.3.132.0.35
+ static const uint8_t kOIDP521[] = {0x2b, 0x81, 0x04, 0x00, 0x23};
+ out->curves[0].nid = NID_secp521r1;
+ out->curves[0].oid = kOIDP521;
+ out->curves[0].oid_len = sizeof(kOIDP521);
+ out->curves[0].comment = "NIST P-521";
+ out->curves[0].param_len = 66;
+ out->curves[0].params = kP521Params;
+ out->curves[0].method = EC_GFp_mont_method();
+
+ // 1.3.132.0.34
+ static const uint8_t kOIDP384[] = {0x2b, 0x81, 0x04, 0x00, 0x22};
+ out->curves[1].nid = NID_secp384r1;
+ out->curves[1].oid = kOIDP384;
+ out->curves[1].oid_len = sizeof(kOIDP384);
+ out->curves[1].comment = "NIST P-384";
+ out->curves[1].param_len = 48;
+ out->curves[1].params = kP384Params;
+ out->curves[1].method = EC_GFp_mont_method();
+
+ // 1.2.840.10045.3.1.7
+ static const uint8_t kOIDP256[] = {0x2a, 0x86, 0x48, 0xce,
+ 0x3d, 0x03, 0x01, 0x07};
+ out->curves[2].nid = NID_X9_62_prime256v1;
+ out->curves[2].oid = kOIDP256;
+ out->curves[2].oid_len = sizeof(kOIDP256);
+ out->curves[2].comment = "NIST P-256";
+ out->curves[2].param_len = 32;
+ out->curves[2].params = kP256Params;
+ out->curves[2].method =
+#if !defined(OPENSSL_NO_ASM) && \
+ (defined(OPENSSL_X86_64) || defined(OPENSSL_AARCH64)) && \
+ !defined(OPENSSL_SMALL)
+ EC_GFp_nistz256_method();
+#else
+ EC_GFp_nistp256_method();
+#endif
+
+ // 1.3.132.0.33
+ static const uint8_t kOIDP224[] = {0x2b, 0x81, 0x04, 0x00, 0x21};
+ out->curves[3].nid = NID_secp224r1;
+ out->curves[3].oid = kOIDP224;
+ out->curves[3].oid_len = sizeof(kOIDP224);
+ out->curves[3].comment = "NIST P-224";
+ out->curves[3].param_len = 28;
+ out->curves[3].params = kP224Params;
+ out->curves[3].method =
+#if defined(BORINGSSL_HAS_UINT128) && !defined(OPENSSL_SMALL)
+ EC_GFp_nistp224_method();
+#else
+ EC_GFp_mont_method();
+#endif
+}
+
+EC_GROUP *ec_group_new(const EC_METHOD *meth) {
+ EC_GROUP *ret;
+
+ if (meth == NULL) {
+ OPENSSL_PUT_ERROR(EC, EC_R_SLOT_FULL);
+ return NULL;
+ }
+
+ if (meth->group_init == 0) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return NULL;
+ }
+
+ ret = OPENSSL_malloc(sizeof(EC_GROUP));
+ if (ret == NULL) {
+ return NULL;
+ }
+ OPENSSL_memset(ret, 0, sizeof(EC_GROUP));
+
+ ret->references = 1;
+ ret->meth = meth;
+ BN_init(&ret->order);
+
+ if (!meth->group_init(ret)) {
+ OPENSSL_free(ret);
+ return NULL;
+ }
+
+ return ret;
+}
+
+static int ec_group_set_generator(EC_GROUP *group, const EC_AFFINE *generator,
+ const BIGNUM *order) {
+ assert(group->generator == NULL);
+
+ if (!BN_copy(&group->order, order)) {
+ return 0;
+ }
+ // Store the order in minimal form, so it can be used with |BN_ULONG| arrays.
+ bn_set_minimal_width(&group->order);
+
+ BN_MONT_CTX_free(group->order_mont);
+ group->order_mont = BN_MONT_CTX_new_for_modulus(&group->order, NULL);
+ if (group->order_mont == NULL) {
+ return 0;
+ }
+
+ group->field_greater_than_order = BN_cmp(&group->field, order) > 0;
+ if (group->field_greater_than_order) {
+ BIGNUM tmp;
+ BN_init(&tmp);
+ int ok =
+ BN_sub(&tmp, &group->field, order) &&
+ bn_copy_words(group->field_minus_order.words, group->field.width, &tmp);
+ BN_free(&tmp);
+ if (!ok) {
+ return 0;
+ }
+ }
+
+ group->generator = EC_POINT_new(group);
+ if (group->generator == NULL) {
+ return 0;
+ }
+ ec_affine_to_jacobian(group, &group->generator->raw, generator);
+ assert(ec_felem_equal(group, &group->one, &group->generator->raw.Z));
+
+ // Avoid a reference cycle. |group->generator| does not maintain an owning
+ // pointer to |group|.
+ int is_zero = CRYPTO_refcount_dec_and_test_zero(&group->references);
+
+ assert(!is_zero);
+ (void)is_zero;
+ return 1;
+}
+
+EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
+ const BIGNUM *b, BN_CTX *ctx) {
+ if (BN_num_bytes(p) > EC_MAX_BYTES) {
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_FIELD);
+ return NULL;
+ }
+
+ BN_CTX *new_ctx = NULL;
+ if (ctx == NULL) {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL) {
+ return NULL;
+ }
+ }
+
+ // Historically, |a| and |b| were not required to be fully reduced.
+ // TODO(davidben): Can this be removed?
+ EC_GROUP *ret = NULL;
+ BN_CTX_start(ctx);
+ BIGNUM *a_reduced = BN_CTX_get(ctx);
+ BIGNUM *b_reduced = BN_CTX_get(ctx);
+ if (a_reduced == NULL || b_reduced == NULL ||
+ !BN_nnmod(a_reduced, a, p, ctx) ||
+ !BN_nnmod(b_reduced, b, p, ctx)) {
+ goto err;
+ }
+
+ ret = ec_group_new(EC_GFp_mont_method());
+ if (ret == NULL ||
+ !ret->meth->group_set_curve(ret, p, a_reduced, b_reduced, ctx)) {
+ EC_GROUP_free(ret);
+ ret = NULL;
+ goto err;
+ }
+
+err:
+ BN_CTX_end(ctx);
+ BN_CTX_free(new_ctx);
+ return ret;
+}
+
+int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
+ const BIGNUM *order, const BIGNUM *cofactor) {
+ if (group->curve_name != NID_undef || group->generator != NULL ||
+ generator->group != group) {
+ // |EC_GROUP_set_generator| may only be used with |EC_GROUP|s returned by
+ // |EC_GROUP_new_curve_GFp| and may only used once on each group.
+ // |generator| must have been created from |EC_GROUP_new_curve_GFp|, not a
+ // copy, so that |generator->group->generator| is set correctly.
+ OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+
+ if (BN_num_bytes(order) > EC_MAX_BYTES) {
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_GROUP_ORDER);
+ return 0;
+ }
+
+ // Require a cofactor of one for custom curves, which implies prime order.
+ if (!BN_is_one(cofactor)) {
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_COFACTOR);
+ return 0;
+ }
+
+ // Require that p < 2×order. This simplifies some ECDSA operations.
+ //
+ // Note any curve which did not satisfy this must have been invalid or use a
+ // tiny prime (less than 17). See the proof in |field_element_to_scalar| in
+ // the ECDSA implementation.
+ int ret = 0;
+ BIGNUM *tmp = BN_new();
+ if (tmp == NULL ||
+ !BN_lshift1(tmp, order)) {
+ goto err;
+ }
+ if (BN_cmp(tmp, &group->field) <= 0) {
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_GROUP_ORDER);
+ goto err;
+ }
+
+ EC_AFFINE affine;
+ if (!ec_jacobian_to_affine(group, &affine, &generator->raw) ||
+ !ec_group_set_generator(group, &affine, order)) {
+ goto err;
+ }
+
+ ret = 1;
+
+err:
+ BN_free(tmp);
+ return ret;
+}
+
+static EC_GROUP *ec_group_new_from_data(const struct built_in_curve *curve) {
+ EC_GROUP *group = NULL;
+ BIGNUM *p = NULL, *a = NULL, *b = NULL, *order = NULL;
+ int ok = 0;
+
+ BN_CTX *ctx = BN_CTX_new();
+ if (ctx == NULL) {
+ goto err;
+ }
+
+ const unsigned param_len = curve->param_len;
+ const uint8_t *params = curve->params;
+
+ if (!(p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) ||
+ !(a = BN_bin2bn(params + 1 * param_len, param_len, NULL)) ||
+ !(b = BN_bin2bn(params + 2 * param_len, param_len, NULL)) ||
+ !(order = BN_bin2bn(params + 5 * param_len, param_len, NULL))) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
+ goto err;
+ }
+
+ group = ec_group_new(curve->method);
+ if (group == NULL ||
+ !group->meth->group_set_curve(group, p, a, b, ctx)) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
+ goto err;
+ }
+
+ EC_AFFINE G;
+ EC_FELEM x, y;
+ if (!ec_felem_from_bytes(group, &x, params + 3 * param_len, param_len) ||
+ !ec_felem_from_bytes(group, &y, params + 4 * param_len, param_len) ||
+ !ec_point_set_affine_coordinates(group, &G, &x, &y)) {
+ goto err;
+ }
+
+ if (!ec_group_set_generator(group, &G, order)) {
+ goto err;
+ }
+
+ ok = 1;
+
+err:
+ if (!ok) {
+ EC_GROUP_free(group);
+ group = NULL;
+ }
+ BN_CTX_free(ctx);
+ BN_free(p);
+ BN_free(a);
+ BN_free(b);
+ BN_free(order);
+ return group;
+}
+
+// Built-in groups are allocated lazily and static once allocated.
+// TODO(davidben): Make these actually static. https://crbug.com/boringssl/20.
+struct built_in_groups_st {
+ EC_GROUP *groups[OPENSSL_NUM_BUILT_IN_CURVES];
+};
+DEFINE_BSS_GET(struct built_in_groups_st, built_in_groups)
+DEFINE_STATIC_MUTEX(built_in_groups_lock)
+
+EC_GROUP *EC_GROUP_new_by_curve_name(int nid) {
+ struct built_in_groups_st *groups = built_in_groups_bss_get();
+ EC_GROUP **group_ptr = NULL;
+ const struct built_in_curves *const curves = OPENSSL_built_in_curves();
+ const struct built_in_curve *curve = NULL;
+ for (size_t i = 0; i < OPENSSL_NUM_BUILT_IN_CURVES; i++) {
+ if (curves->curves[i].nid == nid) {
+ curve = &curves->curves[i];
+ group_ptr = &groups->groups[i];
+ break;
+ }
+ }
+
+ if (curve == NULL) {
+ OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP);
+ return NULL;
+ }
+
+ CRYPTO_STATIC_MUTEX_lock_read(built_in_groups_lock_bss_get());
+ EC_GROUP *ret = *group_ptr;
+ CRYPTO_STATIC_MUTEX_unlock_read(built_in_groups_lock_bss_get());
+ if (ret != NULL) {
+ return ret;
+ }
+
+ ret = ec_group_new_from_data(curve);
+ if (ret == NULL) {
+ return NULL;
+ }
+
+ EC_GROUP *to_free = NULL;
+ CRYPTO_STATIC_MUTEX_lock_write(built_in_groups_lock_bss_get());
+ if (*group_ptr == NULL) {
+ *group_ptr = ret;
+ // Filling in |ret->curve_name| makes |EC_GROUP_free| and |EC_GROUP_dup|
+ // into no-ops. At this point, |ret| is considered static.
+ ret->curve_name = nid;
+ } else {
+ to_free = ret;
+ ret = *group_ptr;
+ }
+ CRYPTO_STATIC_MUTEX_unlock_write(built_in_groups_lock_bss_get());
+
+ EC_GROUP_free(to_free);
+ return ret;
+}
+
+void EC_GROUP_free(EC_GROUP *group) {
+ if (group == NULL ||
+ // Built-in curves are static.
+ group->curve_name != NID_undef ||
+ !CRYPTO_refcount_dec_and_test_zero(&group->references)) {
+ return;
+ }
+
+ if (group->meth->group_finish != NULL) {
+ group->meth->group_finish(group);
+ }
+
+ ec_point_free(group->generator, 0 /* don't free group */);
+ BN_free(&group->order);
+ BN_MONT_CTX_free(group->order_mont);
+
+ OPENSSL_free(group);
+}
+
+EC_GROUP *EC_GROUP_dup(const EC_GROUP *a) {
+ if (a == NULL ||
+ // Built-in curves are static.
+ a->curve_name != NID_undef) {
+ return (EC_GROUP *)a;
+ }
+
+ // Groups are logically immutable (but for |EC_GROUP_set_generator| which must
+ // be called early on), so we simply take a reference.
+ EC_GROUP *group = (EC_GROUP *)a;
+ CRYPTO_refcount_inc(&group->references);
+ return group;
+}
+
+int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ignored) {
+ // Note this function returns 0 if equal and non-zero otherwise.
+ if (a == b) {
+ return 0;
+ }
+ if (a->curve_name != b->curve_name) {
+ return 1;
+ }
+ if (a->curve_name != NID_undef) {
+ // Built-in curves may be compared by curve name alone.
+ return 0;
+ }
+
+ // |a| and |b| are both custom curves. We compare the entire curve
+ // structure. If |a| or |b| is incomplete (due to legacy OpenSSL mistakes,
+ // custom curve construction is sadly done in two parts) but otherwise not the
+ // same object, we consider them always unequal.
+ return a->meth != b->meth ||
+ a->generator == NULL ||
+ b->generator == NULL ||
+ BN_cmp(&a->order, &b->order) != 0 ||
+ BN_cmp(&a->field, &b->field) != 0 ||
+ !ec_felem_equal(a, &a->a, &b->a) ||
+ !ec_felem_equal(a, &a->b, &b->b) ||
+ !ec_GFp_simple_points_equal(a, &a->generator->raw, &b->generator->raw);
+}
+
+const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) {
+ return group->generator;
+}
+
+const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group) {
+ assert(!BN_is_zero(&group->order));
+ return &group->order;
+}
+
+int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) {
+ if (BN_copy(order, EC_GROUP_get0_order(group)) == NULL) {
+ return 0;
+ }
+ return 1;
+}
+
+int EC_GROUP_order_bits(const EC_GROUP *group) {
+ return BN_num_bits(&group->order);
+}
+
+int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor,
+ BN_CTX *ctx) {
+ // All |EC_GROUP|s have cofactor 1.
+ return BN_set_word(cofactor, 1);
+}
+
+int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *out_p, BIGNUM *out_a,
+ BIGNUM *out_b, BN_CTX *ctx) {
+ return ec_GFp_simple_group_get_curve(group, out_p, out_a, out_b);
+}
+
+int EC_GROUP_get_curve_name(const EC_GROUP *group) { return group->curve_name; }
+
+unsigned EC_GROUP_get_degree(const EC_GROUP *group) {
+ return BN_num_bits(&group->field);
+}
+
+const char *EC_curve_nid2nist(int nid) {
+ switch (nid) {
+ case NID_secp224r1:
+ return "P-224";
+ case NID_X9_62_prime256v1:
+ return "P-256";
+ case NID_secp384r1:
+ return "P-384";
+ case NID_secp521r1:
+ return "P-521";
+ }
+ return NULL;
+}
+
+int EC_curve_nist2nid(const char *name) {
+ if (strcmp(name, "P-224") == 0) {
+ return NID_secp224r1;
+ }
+ if (strcmp(name, "P-256") == 0) {
+ return NID_X9_62_prime256v1;
+ }
+ if (strcmp(name, "P-384") == 0) {
+ return NID_secp384r1;
+ }
+ if (strcmp(name, "P-521") == 0) {
+ return NID_secp521r1;
+ }
+ return NID_undef;
+}
+
+EC_POINT *EC_POINT_new(const EC_GROUP *group) {
+ if (group == NULL) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
+ return NULL;
+ }
+
+ EC_POINT *ret = OPENSSL_malloc(sizeof *ret);
+ if (ret == NULL) {
+ return NULL;
+ }
+
+ ret->group = EC_GROUP_dup(group);
+ ec_GFp_simple_point_init(&ret->raw);
+ return ret;
+}
+
+static void ec_point_free(EC_POINT *point, int free_group) {
+ if (!point) {
+ return;
+ }
+ if (free_group) {
+ EC_GROUP_free(point->group);
+ }
+ OPENSSL_free(point);
+}
+
+void EC_POINT_free(EC_POINT *point) {
+ ec_point_free(point, 1 /* free group */);
+}
+
+void EC_POINT_clear_free(EC_POINT *point) { EC_POINT_free(point); }
+
+int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) {
+ if (EC_GROUP_cmp(dest->group, src->group, NULL) != 0) {
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
+ if (dest == src) {
+ return 1;
+ }
+ ec_GFp_simple_point_copy(&dest->raw, &src->raw);
+ return 1;
+}
+
+EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) {
+ if (a == NULL) {
+ return NULL;
+ }
+
+ EC_POINT *ret = EC_POINT_new(group);
+ if (ret == NULL ||
+ !EC_POINT_copy(ret, a)) {
+ EC_POINT_free(ret);
+ return NULL;
+ }
+
+ return ret;
+}
+
+int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) {
+ if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
+ ec_GFp_simple_point_set_to_infinity(group, &point->raw);
+ return 1;
+}
+
+int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) {
+ if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
+ return ec_GFp_simple_is_at_infinity(group, &point->raw);
+}
+
+int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
+ BN_CTX *ctx) {
+ if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
+ return ec_GFp_simple_is_on_curve(group, &point->raw);
+}
+
+int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
+ BN_CTX *ctx) {
+ if (EC_GROUP_cmp(group, a->group, NULL) != 0 ||
+ EC_GROUP_cmp(group, b->group, NULL) != 0) {
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
+ return -1;
+ }
+
+ // Note |EC_POINT_cmp| returns zero for equality and non-zero for inequality.
+ return ec_GFp_simple_points_equal(group, &a->raw, &b->raw) ? 0 : 1;
+}
+
+int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
+ const EC_POINT *point, BIGNUM *x,
+ BIGNUM *y, BN_CTX *ctx) {
+ if (group->meth->point_get_affine_coordinates == 0) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+ if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
+ EC_FELEM x_felem, y_felem;
+ if (!group->meth->point_get_affine_coordinates(group, &point->raw,
+ x == NULL ? NULL : &x_felem,
+ y == NULL ? NULL : &y_felem) ||
+ (x != NULL && !ec_felem_to_bignum(group, x, &x_felem)) ||
+ (y != NULL && !ec_felem_to_bignum(group, y, &y_felem))) {
+ return 0;
+ }
+ return 1;
+}
+
+int EC_POINT_get_affine_coordinates(const EC_GROUP *group,
+ const EC_POINT *point, BIGNUM *x, BIGNUM *y,
+ BN_CTX *ctx) {
+ return EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx);
+}
+
+void ec_affine_to_jacobian(const EC_GROUP *group, EC_JACOBIAN *out,
+ const EC_AFFINE *p) {
+ out->X = p->X;
+ out->Y = p->Y;
+ out->Z = group->one;
+}
+
+int ec_jacobian_to_affine(const EC_GROUP *group, EC_AFFINE *out,
+ const EC_JACOBIAN *p) {
+ return group->meth->point_get_affine_coordinates(group, p, &out->X, &out->Y);
+}
+
+int ec_jacobian_to_affine_batch(const EC_GROUP *group, EC_AFFINE *out,
+ const EC_JACOBIAN *in, size_t num) {
+ if (group->meth->jacobian_to_affine_batch == NULL) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+ return group->meth->jacobian_to_affine_batch(group, out, in, num);
+}
+
+int ec_point_set_affine_coordinates(const EC_GROUP *group, EC_AFFINE *out,
+ const EC_FELEM *x, const EC_FELEM *y) {
+ void (*const felem_mul)(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a,
+ const EC_FELEM *b) = group->meth->felem_mul;
+ void (*const felem_sqr)(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a) =
+ group->meth->felem_sqr;
+
+ // Check if the point is on the curve.
+ EC_FELEM lhs, rhs;
+ felem_sqr(group, &lhs, y); // lhs = y^2
+ felem_sqr(group, &rhs, x); // rhs = x^2
+ ec_felem_add(group, &rhs, &rhs, &group->a); // rhs = x^2 + a
+ felem_mul(group, &rhs, &rhs, x); // rhs = x^3 + ax
+ ec_felem_add(group, &rhs, &rhs, &group->b); // rhs = x^3 + ax + b
+ if (!ec_felem_equal(group, &lhs, &rhs)) {
+ OPENSSL_PUT_ERROR(EC, EC_R_POINT_IS_NOT_ON_CURVE);
+ // In the event of an error, defend against the caller not checking the
+ // return value by setting a known safe value. Note this may not be possible
+ // if the caller is in the process of constructing an arbitrary group and
+ // the generator is missing.
+ if (group->generator != NULL) {
+ assert(ec_felem_equal(group, &group->one, &group->generator->raw.Z));
+ out->X = group->generator->raw.X;
+ out->Y = group->generator->raw.Y;
+ }
+ return 0;
+ }
+
+ out->X = *x;
+ out->Y = *y;
+ return 1;
+}
+
+int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
+ const BIGNUM *x, const BIGNUM *y,
+ BN_CTX *ctx) {
+ if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
+
+ if (x == NULL || y == NULL) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ EC_FELEM x_felem, y_felem;
+ EC_AFFINE affine;
+ if (!ec_bignum_to_felem(group, &x_felem, x) ||
+ !ec_bignum_to_felem(group, &y_felem, y) ||
+ !ec_point_set_affine_coordinates(group, &affine, &x_felem, &y_felem)) {
+ // In the event of an error, defend against the caller not checking the
+ // return value by setting a known safe value.
+ ec_set_to_safe_point(group, &point->raw);
+ return 0;
+ }
+
+ ec_affine_to_jacobian(group, &point->raw, &affine);
+ return 1;
+}
+
+int EC_POINT_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point,
+ const BIGNUM *x, const BIGNUM *y,
+ BN_CTX *ctx) {
+ return EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx);
+}
+
+int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
+ const EC_POINT *b, BN_CTX *ctx) {
+ if (EC_GROUP_cmp(group, r->group, NULL) != 0 ||
+ EC_GROUP_cmp(group, a->group, NULL) != 0 ||
+ EC_GROUP_cmp(group, b->group, NULL) != 0) {
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
+ group->meth->add(group, &r->raw, &a->raw, &b->raw);
+ return 1;
+}
+
+int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
+ BN_CTX *ctx) {
+ if (EC_GROUP_cmp(group, r->group, NULL) != 0 ||
+ EC_GROUP_cmp(group, a->group, NULL) != 0) {
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
+ group->meth->dbl(group, &r->raw, &a->raw);
+ return 1;
+}
+
+
+int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) {
+ if (EC_GROUP_cmp(group, a->group, NULL) != 0) {
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
+ ec_GFp_simple_invert(group, &a->raw);
+ return 1;
+}
+
+static int arbitrary_bignum_to_scalar(const EC_GROUP *group, EC_SCALAR *out,
+ const BIGNUM *in, BN_CTX *ctx) {
+ if (ec_bignum_to_scalar(group, out, in)) {
+ return 1;
+ }
+
+ ERR_clear_error();
+
+ // This is an unusual input, so we do not guarantee constant-time processing.
+ const BIGNUM *order = &group->order;
+ BN_CTX_start(ctx);
+ BIGNUM *tmp = BN_CTX_get(ctx);
+ int ok = tmp != NULL &&
+ BN_nnmod(tmp, in, order, ctx) &&
+ ec_bignum_to_scalar(group, out, tmp);
+ BN_CTX_end(ctx);
+ return ok;
+}
+
+int ec_point_mul_no_self_test(const EC_GROUP *group, EC_POINT *r,
+ const BIGNUM *g_scalar, const EC_POINT *p,
+ const BIGNUM *p_scalar, BN_CTX *ctx) {
+ // Previously, this function set |r| to the point at infinity if there was
+ // nothing to multiply. But, nobody should be calling this function with
+ // nothing to multiply in the first place.
+ if ((g_scalar == NULL && p_scalar == NULL) ||
+ (p == NULL) != (p_scalar == NULL)) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ if (EC_GROUP_cmp(group, r->group, NULL) != 0 ||
+ (p != NULL && EC_GROUP_cmp(group, p->group, NULL) != 0)) {
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
+
+ int ret = 0;
+ BN_CTX *new_ctx = NULL;
+ if (ctx == NULL) {
+ new_ctx = BN_CTX_new();
+ if (new_ctx == NULL) {
+ goto err;
+ }
+ ctx = new_ctx;
+ }
+
+ // If both |g_scalar| and |p_scalar| are non-NULL,
+ // |ec_point_mul_scalar_public| would share the doublings between the two
+ // products, which would be more efficient. However, we conservatively assume
+ // the caller needs a constant-time operation. (ECDSA verification does not
+ // use this function.)
+ //
+ // Previously, the low-level constant-time multiplication function aligned
+ // with this function's calling convention, but this was misleading. Curves
+ // which combined the two multiplications did not avoid the doubling case
+ // in the incomplete addition formula and were not constant-time.
+
+ if (g_scalar != NULL) {
+ EC_SCALAR scalar;
+ if (!arbitrary_bignum_to_scalar(group, &scalar, g_scalar, ctx) ||
+ !ec_point_mul_scalar_base(group, &r->raw, &scalar)) {
+ goto err;
+ }
+ }
+
+ if (p_scalar != NULL) {
+ EC_SCALAR scalar;
+ EC_JACOBIAN tmp;
+ if (!arbitrary_bignum_to_scalar(group, &scalar, p_scalar, ctx) ||
+ !ec_point_mul_scalar(group, &tmp, &p->raw, &scalar)) {
+ goto err;
+ }
+ if (g_scalar == NULL) {
+ OPENSSL_memcpy(&r->raw, &tmp, sizeof(EC_JACOBIAN));
+ } else {
+ group->meth->add(group, &r->raw, &r->raw, &tmp);
+ }
+ }
+
+ ret = 1;
+
+err:
+ BN_CTX_free(new_ctx);
+ return ret;
+}
+
+int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
+ const EC_POINT *p, const BIGNUM *p_scalar, BN_CTX *ctx) {
+ boringssl_ensure_ecc_self_test();
+
+ return ec_point_mul_no_self_test(group, r, g_scalar, p, p_scalar, ctx);
+}
+
+int ec_point_mul_scalar_public(const EC_GROUP *group, EC_JACOBIAN *r,
+ const EC_SCALAR *g_scalar, const EC_JACOBIAN *p,
+ const EC_SCALAR *p_scalar) {
+ if (g_scalar == NULL || p_scalar == NULL || p == NULL) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ if (group->meth->mul_public == NULL) {
+ return group->meth->mul_public_batch(group, r, g_scalar, p, p_scalar, 1);
+ }
+
+ group->meth->mul_public(group, r, g_scalar, p, p_scalar);
+ return 1;
+}
+
+int ec_point_mul_scalar_public_batch(const EC_GROUP *group, EC_JACOBIAN *r,
+ const EC_SCALAR *g_scalar,
+ const EC_JACOBIAN *points,
+ const EC_SCALAR *scalars, size_t num) {
+ if (group->meth->mul_public_batch == NULL) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+
+ return group->meth->mul_public_batch(group, r, g_scalar, points, scalars,
+ num);
+}
+
+int ec_point_mul_scalar(const EC_GROUP *group, EC_JACOBIAN *r,
+ const EC_JACOBIAN *p, const EC_SCALAR *scalar) {
+ if (p == NULL || scalar == NULL) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ group->meth->mul(group, r, p, scalar);
+
+ // Check the result is on the curve to defend against fault attacks or bugs.
+ // This has negligible cost compared to the multiplication.
+ if (!ec_GFp_simple_is_on_curve(group, r)) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+
+ return 1;
+}
+
+int ec_point_mul_scalar_base(const EC_GROUP *group, EC_JACOBIAN *r,
+ const EC_SCALAR *scalar) {
+ if (scalar == NULL) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ group->meth->mul_base(group, r, scalar);
+
+ // Check the result is on the curve to defend against fault attacks or bugs.
+ // This has negligible cost compared to the multiplication.
+ if (!ec_GFp_simple_is_on_curve(group, r)) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+
+ return 1;
+}
+
+int ec_point_mul_scalar_batch(const EC_GROUP *group, EC_JACOBIAN *r,
+ const EC_JACOBIAN *p0, const EC_SCALAR *scalar0,
+ const EC_JACOBIAN *p1, const EC_SCALAR *scalar1,
+ const EC_JACOBIAN *p2,
+ const EC_SCALAR *scalar2) {
+ if (group->meth->mul_batch == NULL) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+
+ group->meth->mul_batch(group, r, p0, scalar0, p1, scalar1, p2, scalar2);
+
+ // Check the result is on the curve to defend against fault attacks or bugs.
+ // This has negligible cost compared to the multiplication.
+ if (!ec_GFp_simple_is_on_curve(group, r)) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+
+ return 1;
+}
+
+int ec_init_precomp(const EC_GROUP *group, EC_PRECOMP *out,
+ const EC_JACOBIAN *p) {
+ if (group->meth->init_precomp == NULL) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+
+ return group->meth->init_precomp(group, out, p);
+}
+
+int ec_point_mul_scalar_precomp(const EC_GROUP *group, EC_JACOBIAN *r,
+ const EC_PRECOMP *p0, const EC_SCALAR *scalar0,
+ const EC_PRECOMP *p1, const EC_SCALAR *scalar1,
+ const EC_PRECOMP *p2,
+ const EC_SCALAR *scalar2) {
+ if (group->meth->mul_precomp == NULL) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+
+ group->meth->mul_precomp(group, r, p0, scalar0, p1, scalar1, p2, scalar2);
+
+ // Check the result is on the curve to defend against fault attacks or bugs.
+ // This has negligible cost compared to the multiplication.
+ if (!ec_GFp_simple_is_on_curve(group, r)) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+
+ return 1;
+}
+
+void ec_point_select(const EC_GROUP *group, EC_JACOBIAN *out, BN_ULONG mask,
+ const EC_JACOBIAN *a, const EC_JACOBIAN *b) {
+ ec_felem_select(group, &out->X, mask, &a->X, &b->X);
+ ec_felem_select(group, &out->Y, mask, &a->Y, &b->Y);
+ ec_felem_select(group, &out->Z, mask, &a->Z, &b->Z);
+}
+
+void ec_affine_select(const EC_GROUP *group, EC_AFFINE *out, BN_ULONG mask,
+ const EC_AFFINE *a, const EC_AFFINE *b) {
+ ec_felem_select(group, &out->X, mask, &a->X, &b->X);
+ ec_felem_select(group, &out->Y, mask, &a->Y, &b->Y);
+}
+
+void ec_precomp_select(const EC_GROUP *group, EC_PRECOMP *out, BN_ULONG mask,
+ const EC_PRECOMP *a, const EC_PRECOMP *b) {
+ static_assert(sizeof(out->comb) == sizeof(*out),
+ "out->comb does not span the entire structure");
+ for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(out->comb); i++) {
+ ec_affine_select(group, &out->comb[i], mask, &a->comb[i], &b->comb[i]);
+ }
+}
+
+int ec_cmp_x_coordinate(const EC_GROUP *group, const EC_JACOBIAN *p,
+ const EC_SCALAR *r) {
+ return group->meth->cmp_x_coordinate(group, p, r);
+}
+
+int ec_get_x_coordinate_as_scalar(const EC_GROUP *group, EC_SCALAR *out,
+ const EC_JACOBIAN *p) {
+ uint8_t bytes[EC_MAX_BYTES];
+ size_t len;
+ if (!ec_get_x_coordinate_as_bytes(group, bytes, &len, sizeof(bytes), p)) {
+ return 0;
+ }
+
+ // The x-coordinate is bounded by p, but we need a scalar, bounded by the
+ // order. These may not have the same size. However, we must have p < 2×order,
+ // assuming p is not tiny (p >= 17).
+ //
+ // Thus |bytes| will fit in |order.width + 1| words, and we can reduce by
+ // performing at most one subtraction.
+ //
+ // Proof: We only work with prime order curves, so the number of points on
+ // the curve is the order. Thus Hasse's theorem gives:
+ //
+ // |order - (p + 1)| <= 2×sqrt(p)
+ // p + 1 - order <= 2×sqrt(p)
+ // p + 1 - 2×sqrt(p) <= order
+ // p + 1 - 2×(p/4) < order (p/4 > sqrt(p) for p >= 17)
+ // p/2 < p/2 + 1 < order
+ // p < 2×order
+ //
+ // Additionally, one can manually check this property for built-in curves. It
+ // is enforced for legacy custom curves in |EC_GROUP_set_generator|.
+ const BIGNUM *order = &group->order;
+ BN_ULONG words[EC_MAX_WORDS + 1] = {0};
+ bn_big_endian_to_words(words, order->width + 1, bytes, len);
+ bn_reduce_once(out->words, words, /*carry=*/words[order->width], order->d,
+ order->width);
+ return 1;
+}
+
+int ec_get_x_coordinate_as_bytes(const EC_GROUP *group, uint8_t *out,
+ size_t *out_len, size_t max_out,
+ const EC_JACOBIAN *p) {
+ size_t len = BN_num_bytes(&group->field);
+ assert(len <= EC_MAX_BYTES);
+ if (max_out < len) {
+ OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL);
+ return 0;
+ }
+
+ EC_FELEM x;
+ if (!group->meth->point_get_affine_coordinates(group, p, &x, NULL)) {
+ return 0;
+ }
+
+ ec_felem_to_bytes(group, out, out_len, &x);
+ *out_len = len;
+ return 1;
+}
+
+void ec_set_to_safe_point(const EC_GROUP *group, EC_JACOBIAN *out) {
+ if (group->generator != NULL) {
+ ec_GFp_simple_point_copy(out, &group->generator->raw);
+ } else {
+ // The generator can be missing if the caller is in the process of
+ // constructing an arbitrary group. In this case, we give up and use the
+ // point at infinity.
+ ec_GFp_simple_point_set_to_infinity(group, out);
+ }
+}
+
+void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag) {}
+
+int EC_GROUP_get_asn1_flag(const EC_GROUP *group) {
+ return OPENSSL_EC_NAMED_CURVE;
+}
+
+const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group) {
+ // This function exists purely to give callers a way to call
+ // |EC_METHOD_get_field_type|. cryptography.io crashes if |EC_GROUP_method_of|
+ // returns NULL, so return some other garbage pointer.
+ return (const EC_METHOD *)0x12340000;
+}
+
+int EC_METHOD_get_field_type(const EC_METHOD *meth) {
+ return NID_X9_62_prime_field;
+}
+
+void EC_GROUP_set_point_conversion_form(EC_GROUP *group,
+ point_conversion_form_t form) {
+ if (form != POINT_CONVERSION_UNCOMPRESSED) {
+ abort();
+ }
+}
+
+size_t EC_get_builtin_curves(EC_builtin_curve *out_curves,
+ size_t max_num_curves) {
+ const struct built_in_curves *const curves = OPENSSL_built_in_curves();
+
+ for (size_t i = 0; i < max_num_curves && i < OPENSSL_NUM_BUILT_IN_CURVES;
+ i++) {
+ out_curves[i].comment = curves->curves[i].comment;
+ out_curves[i].nid = curves->curves[i].nid;
+ }
+
+ return OPENSSL_NUM_BUILT_IN_CURVES;
+}
diff --git a/src/crypto/fipsmodule/ec/ec_key.c b/src/crypto/fipsmodule/ec/ec_key.c
new file mode 100644
index 0000000..84a29ab
--- /dev/null
+++ b/src/crypto/fipsmodule/ec/ec_key.c
@@ -0,0 +1,546 @@
+/* Originally written by Bodo Moeller for the OpenSSL project.
+ * ====================================================================
+ * Copyright (c) 1998-2005 The OpenSSL Project. 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.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS 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.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * The elliptic curve binary polynomial software is originally written by
+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems
+ * Laboratories. */
+
+#include <openssl/ec_key.h>
+
+#include <string.h>
+
+#include <openssl/ec.h>
+#include <openssl/ecdsa.h>
+#include <openssl/engine.h>
+#include <openssl/err.h>
+#include <openssl/ex_data.h>
+#include <openssl/mem.h>
+#include <openssl/thread.h>
+
+#include "internal.h"
+#include "../delocate.h"
+#include "../service_indicator/internal.h"
+#include "../../internal.h"
+
+
+DEFINE_STATIC_EX_DATA_CLASS(g_ec_ex_data_class)
+
+static EC_WRAPPED_SCALAR *ec_wrapped_scalar_new(const EC_GROUP *group) {
+ EC_WRAPPED_SCALAR *wrapped = OPENSSL_malloc(sizeof(EC_WRAPPED_SCALAR));
+ if (wrapped == NULL) {
+ return NULL;
+ }
+
+ OPENSSL_memset(wrapped, 0, sizeof(EC_WRAPPED_SCALAR));
+ wrapped->bignum.d = wrapped->scalar.words;
+ wrapped->bignum.width = group->order.width;
+ wrapped->bignum.dmax = group->order.width;
+ wrapped->bignum.flags = BN_FLG_STATIC_DATA;
+ return wrapped;
+}
+
+static void ec_wrapped_scalar_free(EC_WRAPPED_SCALAR *scalar) {
+ OPENSSL_free(scalar);
+}
+
+EC_KEY *EC_KEY_new(void) { return EC_KEY_new_method(NULL); }
+
+EC_KEY *EC_KEY_new_method(const ENGINE *engine) {
+ EC_KEY *ret = OPENSSL_malloc(sizeof(EC_KEY));
+ if (ret == NULL) {
+ return NULL;
+ }
+
+ OPENSSL_memset(ret, 0, sizeof(EC_KEY));
+
+ if (engine) {
+ ret->ecdsa_meth = ENGINE_get_ECDSA_method(engine);
+ }
+ if (ret->ecdsa_meth) {
+ METHOD_ref(ret->ecdsa_meth);
+ }
+
+ ret->conv_form = POINT_CONVERSION_UNCOMPRESSED;
+ ret->references = 1;
+
+ CRYPTO_new_ex_data(&ret->ex_data);
+
+ if (ret->ecdsa_meth && ret->ecdsa_meth->init && !ret->ecdsa_meth->init(ret)) {
+ CRYPTO_free_ex_data(g_ec_ex_data_class_bss_get(), ret, &ret->ex_data);
+ if (ret->ecdsa_meth) {
+ METHOD_unref(ret->ecdsa_meth);
+ }
+ OPENSSL_free(ret);
+ return NULL;
+ }
+
+ return ret;
+}
+
+EC_KEY *EC_KEY_new_by_curve_name(int nid) {
+ EC_KEY *ret = EC_KEY_new();
+ if (ret == NULL) {
+ return NULL;
+ }
+ ret->group = EC_GROUP_new_by_curve_name(nid);
+ if (ret->group == NULL) {
+ EC_KEY_free(ret);
+ return NULL;
+ }
+ return ret;
+}
+
+void EC_KEY_free(EC_KEY *r) {
+ if (r == NULL) {
+ return;
+ }
+
+ if (!CRYPTO_refcount_dec_and_test_zero(&r->references)) {
+ return;
+ }
+
+ if (r->ecdsa_meth) {
+ if (r->ecdsa_meth->finish) {
+ r->ecdsa_meth->finish(r);
+ }
+ METHOD_unref(r->ecdsa_meth);
+ }
+
+ EC_GROUP_free(r->group);
+ EC_POINT_free(r->pub_key);
+ ec_wrapped_scalar_free(r->priv_key);
+
+ CRYPTO_free_ex_data(g_ec_ex_data_class_bss_get(), r, &r->ex_data);
+
+ OPENSSL_free(r);
+}
+
+EC_KEY *EC_KEY_dup(const EC_KEY *src) {
+ if (src == NULL) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
+ return NULL;
+ }
+
+ EC_KEY *ret = EC_KEY_new();
+ if (ret == NULL) {
+ return NULL;
+ }
+
+ if ((src->group != NULL &&
+ !EC_KEY_set_group(ret, src->group)) ||
+ (src->pub_key != NULL &&
+ !EC_KEY_set_public_key(ret, src->pub_key)) ||
+ (src->priv_key != NULL &&
+ !EC_KEY_set_private_key(ret, EC_KEY_get0_private_key(src)))) {
+ EC_KEY_free(ret);
+ return NULL;
+ }
+
+ ret->enc_flag = src->enc_flag;
+ ret->conv_form = src->conv_form;
+ return ret;
+}
+
+int EC_KEY_up_ref(EC_KEY *r) {
+ CRYPTO_refcount_inc(&r->references);
+ return 1;
+}
+
+int EC_KEY_is_opaque(const EC_KEY *key) {
+ return key->ecdsa_meth && (key->ecdsa_meth->flags & ECDSA_FLAG_OPAQUE);
+}
+
+const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key) { return key->group; }
+
+int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group) {
+ // If |key| already has a group, it is an error to switch to another one.
+ if (key->group != NULL) {
+ if (EC_GROUP_cmp(key->group, group, NULL) != 0) {
+ OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH);
+ return 0;
+ }
+ return 1;
+ }
+
+ assert(key->priv_key == NULL);
+ assert(key->pub_key == NULL);
+
+ EC_GROUP_free(key->group);
+ key->group = EC_GROUP_dup(group);
+ return key->group != NULL;
+}
+
+const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key) {
+ return key->priv_key != NULL ? &key->priv_key->bignum : NULL;
+}
+
+int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key) {
+ if (key->group == NULL) {
+ OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PARAMETERS);
+ return 0;
+ }
+
+ EC_WRAPPED_SCALAR *scalar = ec_wrapped_scalar_new(key->group);
+ if (scalar == NULL) {
+ return 0;
+ }
+ if (!ec_bignum_to_scalar(key->group, &scalar->scalar, priv_key) ||
+ ec_scalar_is_zero(key->group, &scalar->scalar)) {
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_PRIVATE_KEY);
+ ec_wrapped_scalar_free(scalar);
+ return 0;
+ }
+ ec_wrapped_scalar_free(key->priv_key);
+ key->priv_key = scalar;
+ return 1;
+}
+
+const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key) {
+ return key->pub_key;
+}
+
+int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key) {
+ if (key->group == NULL) {
+ OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PARAMETERS);
+ return 0;
+ }
+
+ if (pub_key != NULL && EC_GROUP_cmp(key->group, pub_key->group, NULL) != 0) {
+ OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH);
+ return 0;
+ }
+
+ EC_POINT_free(key->pub_key);
+ key->pub_key = EC_POINT_dup(pub_key, key->group);
+ return (key->pub_key == NULL) ? 0 : 1;
+}
+
+unsigned int EC_KEY_get_enc_flags(const EC_KEY *key) { return key->enc_flag; }
+
+void EC_KEY_set_enc_flags(EC_KEY *key, unsigned int flags) {
+ key->enc_flag = flags;
+}
+
+point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key) {
+ return key->conv_form;
+}
+
+void EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform) {
+ key->conv_form = cform;
+}
+
+int EC_KEY_check_key(const EC_KEY *eckey) {
+ if (!eckey || !eckey->group || !eckey->pub_key) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key)) {
+ OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY);
+ return 0;
+ }
+
+ // Test whether the public key is on the elliptic curve.
+ if (!EC_POINT_is_on_curve(eckey->group, eckey->pub_key, NULL)) {
+ OPENSSL_PUT_ERROR(EC, EC_R_POINT_IS_NOT_ON_CURVE);
+ return 0;
+ }
+
+ // Check the public and private keys match.
+ //
+ // NOTE: this is a FIPS pair-wise consistency check for the ECDH case. See SP
+ // 800-56Ar3, page 36.
+ if (eckey->priv_key != NULL) {
+ EC_JACOBIAN point;
+ if (!ec_point_mul_scalar_base(eckey->group, &point,
+ &eckey->priv_key->scalar)) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
+ return 0;
+ }
+ if (!ec_GFp_simple_points_equal(eckey->group, &point,
+ &eckey->pub_key->raw)) {
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_PRIVATE_KEY);
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+int EC_KEY_check_fips(const EC_KEY *key) {
+ int ret = 0;
+ FIPS_service_indicator_lock_state();
+
+ if (EC_KEY_is_opaque(key)) {
+ // Opaque keys can't be checked.
+ OPENSSL_PUT_ERROR(EC, EC_R_PUBLIC_KEY_VALIDATION_FAILED);
+ goto end;
+ }
+
+ if (!EC_KEY_check_key(key)) {
+ goto end;
+ }
+
+ if (key->priv_key) {
+ uint8_t data[16] = {0};
+ ECDSA_SIG *sig = ECDSA_do_sign(data, sizeof(data), key);
+ if (boringssl_fips_break_test("ECDSA_PWCT")) {
+ data[0] = ~data[0];
+ }
+ int ok = sig != NULL &&
+ ECDSA_do_verify(data, sizeof(data), sig, key);
+ ECDSA_SIG_free(sig);
+ if (!ok) {
+ OPENSSL_PUT_ERROR(EC, EC_R_PUBLIC_KEY_VALIDATION_FAILED);
+ goto end;
+ }
+ }
+
+ ret = 1;
+
+end:
+ FIPS_service_indicator_unlock_state();
+ if (ret) {
+ EC_KEY_keygen_verify_service_indicator(key);
+ }
+
+ return ret;
+}
+
+int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, const BIGNUM *x,
+ const BIGNUM *y) {
+ EC_POINT *point = NULL;
+ int ok = 0;
+
+ if (!key || !key->group || !x || !y) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ point = EC_POINT_new(key->group);
+ if (point == NULL ||
+ !EC_POINT_set_affine_coordinates_GFp(key->group, point, x, y, NULL) ||
+ !EC_KEY_set_public_key(key, point) ||
+ !EC_KEY_check_key(key)) {
+ goto err;
+ }
+
+ ok = 1;
+
+err:
+ EC_POINT_free(point);
+ return ok;
+}
+
+int EC_KEY_oct2key(EC_KEY *key, const uint8_t *in, size_t len, BN_CTX *ctx) {
+ if (key->group == NULL) {
+ OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PARAMETERS);
+ return 0;
+ }
+
+ EC_POINT *point = EC_POINT_new(key->group);
+ int ok = point != NULL &&
+ EC_POINT_oct2point(key->group, point, in, len, ctx) &&
+ EC_KEY_set_public_key(key, point);
+ EC_POINT_free(point);
+ return ok;
+}
+
+size_t EC_KEY_key2buf(const EC_KEY *key, point_conversion_form_t form,
+ uint8_t **out_buf, BN_CTX *ctx) {
+ if (key == NULL || key->pub_key == NULL || key->group == NULL) {
+ OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PARAMETERS);
+ return 0;
+ }
+
+ return EC_POINT_point2buf(key->group, key->pub_key, form, out_buf, ctx);
+}
+
+int EC_KEY_oct2priv(EC_KEY *key, const uint8_t *in, size_t len) {
+ if (key->group == NULL) {
+ OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PARAMETERS);
+ return 0;
+ }
+
+ if (len != BN_num_bytes(EC_GROUP_get0_order(key->group))) {
+ OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
+ return 0;
+ }
+
+ BIGNUM *priv_key = BN_bin2bn(in, len, NULL);
+ int ok = priv_key != NULL && //
+ EC_KEY_set_private_key(key, priv_key);
+ BN_free(priv_key);
+ return ok;
+}
+
+size_t EC_KEY_priv2oct(const EC_KEY *key, uint8_t *out, size_t max_out) {
+ if (key->group == NULL || key->priv_key == NULL) {
+ OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PARAMETERS);
+ return 0;
+ }
+
+ size_t len = BN_num_bytes(EC_GROUP_get0_order(key->group));
+ if (out == NULL) {
+ return len;
+ }
+
+ if (max_out < len) {
+ OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL);
+ return 0;
+ }
+
+ size_t bytes_written;
+ ec_scalar_to_bytes(key->group, out, &bytes_written, &key->priv_key->scalar);
+ assert(bytes_written == len);
+ return len;
+}
+
+size_t EC_KEY_priv2buf(const EC_KEY *key, uint8_t **out_buf) {
+ *out_buf = NULL;
+ size_t len = EC_KEY_priv2oct(key, NULL, 0);
+ if (len == 0) {
+ return 0;
+ }
+
+ uint8_t *buf = OPENSSL_malloc(len);
+ if (buf == NULL) {
+ return 0;
+ }
+
+ len = EC_KEY_priv2oct(key, buf, len);
+ if (len == 0) {
+ OPENSSL_free(buf);
+ return 0;
+ }
+
+ *out_buf = buf;
+ return len;
+}
+
+int EC_KEY_generate_key(EC_KEY *key) {
+ if (key == NULL || key->group == NULL) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ // Check that the group order is FIPS compliant (FIPS 186-4 B.4.2).
+ if (BN_num_bits(EC_GROUP_get0_order(key->group)) < 160) {
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_GROUP_ORDER);
+ return 0;
+ }
+
+ static const uint8_t kDefaultAdditionalData[32] = {0};
+ EC_WRAPPED_SCALAR *priv_key = ec_wrapped_scalar_new(key->group);
+ EC_POINT *pub_key = EC_POINT_new(key->group);
+ if (priv_key == NULL || pub_key == NULL ||
+ // Generate the private key by testing candidates (FIPS 186-4 B.4.2).
+ !ec_random_nonzero_scalar(key->group, &priv_key->scalar,
+ kDefaultAdditionalData) ||
+ !ec_point_mul_scalar_base(key->group, &pub_key->raw, &priv_key->scalar)) {
+ EC_POINT_free(pub_key);
+ ec_wrapped_scalar_free(priv_key);
+ return 0;
+ }
+
+ ec_wrapped_scalar_free(key->priv_key);
+ key->priv_key = priv_key;
+ EC_POINT_free(key->pub_key);
+ key->pub_key = pub_key;
+ return 1;
+}
+
+int EC_KEY_generate_key_fips(EC_KEY *eckey) {
+ boringssl_ensure_ecc_self_test();
+
+ if (EC_KEY_generate_key(eckey) && EC_KEY_check_fips(eckey)) {
+ return 1;
+ }
+
+ EC_POINT_free(eckey->pub_key);
+ ec_wrapped_scalar_free(eckey->priv_key);
+ eckey->pub_key = NULL;
+ eckey->priv_key = NULL;
+ return 0;
+}
+
+int EC_KEY_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
+ CRYPTO_EX_dup *dup_unused,
+ CRYPTO_EX_free *free_func) {
+ int index;
+ if (!CRYPTO_get_ex_new_index(g_ec_ex_data_class_bss_get(), &index, argl, argp,
+ free_func)) {
+ return -1;
+ }
+ return index;
+}
+
+int EC_KEY_set_ex_data(EC_KEY *d, int idx, void *arg) {
+ return CRYPTO_set_ex_data(&d->ex_data, idx, arg);
+}
+
+void *EC_KEY_get_ex_data(const EC_KEY *d, int idx) {
+ return CRYPTO_get_ex_data(&d->ex_data, idx);
+}
+
+void EC_KEY_set_asn1_flag(EC_KEY *key, int flag) {}
diff --git a/src/crypto/fipsmodule/ec/ec_montgomery.c b/src/crypto/fipsmodule/ec/ec_montgomery.c
new file mode 100644
index 0000000..eeaee64
--- /dev/null
+++ b/src/crypto/fipsmodule/ec/ec_montgomery.c
@@ -0,0 +1,524 @@
+/* Originally written by Bodo Moeller and Nils Larsch for the OpenSSL project.
+ * ====================================================================
+ * Copyright (c) 1998-2005 The OpenSSL Project. 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.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS 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.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * The elliptic curve binary polynomial software is originally written by
+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems
+ * Laboratories. */
+
+#include <openssl/ec.h>
+
+#include <openssl/bn.h>
+#include <openssl/err.h>
+#include <openssl/mem.h>
+
+#include "../bn/internal.h"
+#include "../delocate.h"
+#include "internal.h"
+
+
+int ec_GFp_mont_group_init(EC_GROUP *group) {
+ int ok;
+
+ ok = ec_GFp_simple_group_init(group);
+ group->mont = NULL;
+ return ok;
+}
+
+void ec_GFp_mont_group_finish(EC_GROUP *group) {
+ BN_MONT_CTX_free(group->mont);
+ group->mont = NULL;
+ ec_GFp_simple_group_finish(group);
+}
+
+int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p,
+ const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) {
+ BN_MONT_CTX_free(group->mont);
+ group->mont = BN_MONT_CTX_new_for_modulus(p, ctx);
+ if (group->mont == NULL) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
+ return 0;
+ }
+
+ if (!ec_GFp_simple_group_set_curve(group, p, a, b, ctx)) {
+ BN_MONT_CTX_free(group->mont);
+ group->mont = NULL;
+ return 0;
+ }
+
+ return 1;
+}
+
+static void ec_GFp_mont_felem_to_montgomery(const EC_GROUP *group,
+ EC_FELEM *out, const EC_FELEM *in) {
+ bn_to_montgomery_small(out->words, in->words, group->field.width,
+ group->mont);
+}
+
+static void ec_GFp_mont_felem_from_montgomery(const EC_GROUP *group,
+ EC_FELEM *out,
+ const EC_FELEM *in) {
+ bn_from_montgomery_small(out->words, group->field.width, in->words,
+ group->field.width, group->mont);
+}
+
+static void ec_GFp_mont_felem_inv0(const EC_GROUP *group, EC_FELEM *out,
+ const EC_FELEM *a) {
+ bn_mod_inverse0_prime_mont_small(out->words, a->words, group->field.width,
+ group->mont);
+}
+
+void ec_GFp_mont_felem_mul(const EC_GROUP *group, EC_FELEM *r,
+ const EC_FELEM *a, const EC_FELEM *b) {
+ bn_mod_mul_montgomery_small(r->words, a->words, b->words, group->field.width,
+ group->mont);
+}
+
+void ec_GFp_mont_felem_sqr(const EC_GROUP *group, EC_FELEM *r,
+ const EC_FELEM *a) {
+ bn_mod_mul_montgomery_small(r->words, a->words, a->words, group->field.width,
+ group->mont);
+}
+
+void ec_GFp_mont_felem_to_bytes(const EC_GROUP *group, uint8_t *out,
+ size_t *out_len, const EC_FELEM *in) {
+ EC_FELEM tmp;
+ ec_GFp_mont_felem_from_montgomery(group, &tmp, in);
+ ec_GFp_simple_felem_to_bytes(group, out, out_len, &tmp);
+}
+
+int ec_GFp_mont_felem_from_bytes(const EC_GROUP *group, EC_FELEM *out,
+ const uint8_t *in, size_t len) {
+ if (!ec_GFp_simple_felem_from_bytes(group, out, in, len)) {
+ return 0;
+ }
+
+ ec_GFp_mont_felem_to_montgomery(group, out, out);
+ return 1;
+}
+
+void ec_GFp_mont_felem_reduce(const EC_GROUP *group, EC_FELEM *out,
+ const BN_ULONG *words, size_t num) {
+ // Convert "from" Montgomery form so the value is reduced mod p.
+ bn_from_montgomery_small(out->words, group->field.width, words, num,
+ group->mont);
+ // Convert "to" Montgomery form to remove the R^-1 factor added.
+ ec_GFp_mont_felem_to_montgomery(group, out, out);
+ // Convert to Montgomery form to match this implementation's representation.
+ ec_GFp_mont_felem_to_montgomery(group, out, out);
+}
+
+void ec_GFp_mont_felem_exp(const EC_GROUP *group, EC_FELEM *out,
+ const EC_FELEM *a, const BN_ULONG *exp,
+ size_t num_exp) {
+ bn_mod_exp_mont_small(out->words, a->words, group->field.width, exp, num_exp,
+ group->mont);
+}
+
+static int ec_GFp_mont_point_get_affine_coordinates(const EC_GROUP *group,
+ const EC_JACOBIAN *point,
+ EC_FELEM *x, EC_FELEM *y) {
+ if (ec_GFp_simple_is_at_infinity(group, point)) {
+ OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY);
+ return 0;
+ }
+
+ // Transform (X, Y, Z) into (x, y) := (X/Z^2, Y/Z^3). Note the check above
+ // ensures |point->Z| is non-zero, so the inverse always exists.
+ EC_FELEM z1, z2;
+ ec_GFp_mont_felem_inv0(group, &z2, &point->Z);
+ ec_GFp_mont_felem_sqr(group, &z1, &z2);
+
+ if (x != NULL) {
+ ec_GFp_mont_felem_mul(group, x, &point->X, &z1);
+ }
+
+ if (y != NULL) {
+ ec_GFp_mont_felem_mul(group, &z1, &z1, &z2);
+ ec_GFp_mont_felem_mul(group, y, &point->Y, &z1);
+ }
+
+ return 1;
+}
+
+static int ec_GFp_mont_jacobian_to_affine_batch(const EC_GROUP *group,
+ EC_AFFINE *out,
+ const EC_JACOBIAN *in,
+ size_t num) {
+ if (num == 0) {
+ return 1;
+ }
+
+ // Compute prefix products of all Zs. Use |out[i].X| as scratch space
+ // to store these values.
+ out[0].X = in[0].Z;
+ for (size_t i = 1; i < num; i++) {
+ ec_GFp_mont_felem_mul(group, &out[i].X, &out[i - 1].X, &in[i].Z);
+ }
+
+ // Some input was infinity iff the product of all Zs is zero.
+ if (ec_felem_non_zero_mask(group, &out[num - 1].X) == 0) {
+ OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY);
+ return 0;
+ }
+
+ // Invert the product of all Zs.
+ EC_FELEM zinvprod;
+ ec_GFp_mont_felem_inv0(group, &zinvprod, &out[num - 1].X);
+ for (size_t i = num - 1; i < num; i--) {
+ // Our loop invariant is that |zinvprod| is Z0^-1 * Z1^-1 * ... * Zi^-1.
+ // Recover Zi^-1 by multiplying by the previous product.
+ EC_FELEM zinv, zinv2;
+ if (i == 0) {
+ zinv = zinvprod;
+ } else {
+ ec_GFp_mont_felem_mul(group, &zinv, &zinvprod, &out[i - 1].X);
+ // Maintain the loop invariant for the next iteration.
+ ec_GFp_mont_felem_mul(group, &zinvprod, &zinvprod, &in[i].Z);
+ }
+
+ // Compute affine coordinates: x = X * Z^-2 and y = Y * Z^-3.
+ ec_GFp_mont_felem_sqr(group, &zinv2, &zinv);
+ ec_GFp_mont_felem_mul(group, &out[i].X, &in[i].X, &zinv2);
+ ec_GFp_mont_felem_mul(group, &out[i].Y, &in[i].Y, &zinv2);
+ ec_GFp_mont_felem_mul(group, &out[i].Y, &out[i].Y, &zinv);
+ }
+
+ return 1;
+}
+
+void ec_GFp_mont_add(const EC_GROUP *group, EC_JACOBIAN *out,
+ const EC_JACOBIAN *a, const EC_JACOBIAN *b) {
+ if (a == b) {
+ ec_GFp_mont_dbl(group, out, a);
+ return;
+ }
+
+ // The method is taken from:
+ // http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#addition-add-2007-bl
+ //
+ // Coq transcription and correctness proof:
+ // <https://github.com/davidben/fiat-crypto/blob/c7b95f62b2a54b559522573310e9b487327d219a/src/Curves/Weierstrass/Jacobian.v#L467>
+ // <https://github.com/davidben/fiat-crypto/blob/c7b95f62b2a54b559522573310e9b487327d219a/src/Curves/Weierstrass/Jacobian.v#L544>
+ EC_FELEM x_out, y_out, z_out;
+ BN_ULONG z1nz = ec_felem_non_zero_mask(group, &a->Z);
+ BN_ULONG z2nz = ec_felem_non_zero_mask(group, &b->Z);
+
+ // z1z1 = z1z1 = z1**2
+ EC_FELEM z1z1;
+ ec_GFp_mont_felem_sqr(group, &z1z1, &a->Z);
+
+ // z2z2 = z2**2
+ EC_FELEM z2z2;
+ ec_GFp_mont_felem_sqr(group, &z2z2, &b->Z);
+
+ // u1 = x1*z2z2
+ EC_FELEM u1;
+ ec_GFp_mont_felem_mul(group, &u1, &a->X, &z2z2);
+
+ // two_z1z2 = (z1 + z2)**2 - (z1z1 + z2z2) = 2z1z2
+ EC_FELEM two_z1z2;
+ ec_felem_add(group, &two_z1z2, &a->Z, &b->Z);
+ ec_GFp_mont_felem_sqr(group, &two_z1z2, &two_z1z2);
+ ec_felem_sub(group, &two_z1z2, &two_z1z2, &z1z1);
+ ec_felem_sub(group, &two_z1z2, &two_z1z2, &z2z2);
+
+ // s1 = y1 * z2**3
+ EC_FELEM s1;
+ ec_GFp_mont_felem_mul(group, &s1, &b->Z, &z2z2);
+ ec_GFp_mont_felem_mul(group, &s1, &s1, &a->Y);
+
+ // u2 = x2*z1z1
+ EC_FELEM u2;
+ ec_GFp_mont_felem_mul(group, &u2, &b->X, &z1z1);
+
+ // h = u2 - u1
+ EC_FELEM h;
+ ec_felem_sub(group, &h, &u2, &u1);
+
+ BN_ULONG xneq = ec_felem_non_zero_mask(group, &h);
+
+ // z_out = two_z1z2 * h
+ ec_GFp_mont_felem_mul(group, &z_out, &h, &two_z1z2);
+
+ // z1z1z1 = z1 * z1z1
+ EC_FELEM z1z1z1;
+ ec_GFp_mont_felem_mul(group, &z1z1z1, &a->Z, &z1z1);
+
+ // s2 = y2 * z1**3
+ EC_FELEM s2;
+ ec_GFp_mont_felem_mul(group, &s2, &b->Y, &z1z1z1);
+
+ // r = (s2 - s1)*2
+ EC_FELEM r;
+ ec_felem_sub(group, &r, &s2, &s1);
+ ec_felem_add(group, &r, &r, &r);
+
+ BN_ULONG yneq = ec_felem_non_zero_mask(group, &r);
+
+ // This case will never occur in the constant-time |ec_GFp_mont_mul|.
+ BN_ULONG is_nontrivial_double = ~xneq & ~yneq & z1nz & z2nz;
+ if (is_nontrivial_double) {
+ ec_GFp_mont_dbl(group, out, a);
+ return;
+ }
+
+ // I = (2h)**2
+ EC_FELEM i;
+ ec_felem_add(group, &i, &h, &h);
+ ec_GFp_mont_felem_sqr(group, &i, &i);
+
+ // J = h * I
+ EC_FELEM j;
+ ec_GFp_mont_felem_mul(group, &j, &h, &i);
+
+ // V = U1 * I
+ EC_FELEM v;
+ ec_GFp_mont_felem_mul(group, &v, &u1, &i);
+
+ // x_out = r**2 - J - 2V
+ ec_GFp_mont_felem_sqr(group, &x_out, &r);
+ ec_felem_sub(group, &x_out, &x_out, &j);
+ ec_felem_sub(group, &x_out, &x_out, &v);
+ ec_felem_sub(group, &x_out, &x_out, &v);
+
+ // y_out = r(V-x_out) - 2 * s1 * J
+ ec_felem_sub(group, &y_out, &v, &x_out);
+ ec_GFp_mont_felem_mul(group, &y_out, &y_out, &r);
+ EC_FELEM s1j;
+ ec_GFp_mont_felem_mul(group, &s1j, &s1, &j);
+ ec_felem_sub(group, &y_out, &y_out, &s1j);
+ ec_felem_sub(group, &y_out, &y_out, &s1j);
+
+ ec_felem_select(group, &x_out, z1nz, &x_out, &b->X);
+ ec_felem_select(group, &out->X, z2nz, &x_out, &a->X);
+ ec_felem_select(group, &y_out, z1nz, &y_out, &b->Y);
+ ec_felem_select(group, &out->Y, z2nz, &y_out, &a->Y);
+ ec_felem_select(group, &z_out, z1nz, &z_out, &b->Z);
+ ec_felem_select(group, &out->Z, z2nz, &z_out, &a->Z);
+}
+
+void ec_GFp_mont_dbl(const EC_GROUP *group, EC_JACOBIAN *r,
+ const EC_JACOBIAN *a) {
+ if (group->a_is_minus3) {
+ // The method is taken from:
+ // http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
+ //
+ // Coq transcription and correctness proof:
+ // <https://github.com/mit-plv/fiat-crypto/blob/79f8b5f39ed609339f0233098dee1a3c4e6b3080/src/Curves/Weierstrass/Jacobian.v#L93>
+ // <https://github.com/mit-plv/fiat-crypto/blob/79f8b5f39ed609339f0233098dee1a3c4e6b3080/src/Curves/Weierstrass/Jacobian.v#L201>
+ EC_FELEM delta, gamma, beta, ftmp, ftmp2, tmptmp, alpha, fourbeta;
+ // delta = z^2
+ ec_GFp_mont_felem_sqr(group, &delta, &a->Z);
+ // gamma = y^2
+ ec_GFp_mont_felem_sqr(group, &gamma, &a->Y);
+ // beta = x*gamma
+ ec_GFp_mont_felem_mul(group, &beta, &a->X, &gamma);
+
+ // alpha = 3*(x-delta)*(x+delta)
+ ec_felem_sub(group, &ftmp, &a->X, &delta);
+ ec_felem_add(group, &ftmp2, &a->X, &delta);
+
+ ec_felem_add(group, &tmptmp, &ftmp2, &ftmp2);
+ ec_felem_add(group, &ftmp2, &ftmp2, &tmptmp);
+ ec_GFp_mont_felem_mul(group, &alpha, &ftmp, &ftmp2);
+
+ // x' = alpha^2 - 8*beta
+ ec_GFp_mont_felem_sqr(group, &r->X, &alpha);
+ ec_felem_add(group, &fourbeta, &beta, &beta);
+ ec_felem_add(group, &fourbeta, &fourbeta, &fourbeta);
+ ec_felem_add(group, &tmptmp, &fourbeta, &fourbeta);
+ ec_felem_sub(group, &r->X, &r->X, &tmptmp);
+
+ // z' = (y + z)^2 - gamma - delta
+ ec_felem_add(group, &delta, &gamma, &delta);
+ ec_felem_add(group, &ftmp, &a->Y, &a->Z);
+ ec_GFp_mont_felem_sqr(group, &r->Z, &ftmp);
+ ec_felem_sub(group, &r->Z, &r->Z, &delta);
+
+ // y' = alpha*(4*beta - x') - 8*gamma^2
+ ec_felem_sub(group, &r->Y, &fourbeta, &r->X);
+ ec_felem_add(group, &gamma, &gamma, &gamma);
+ ec_GFp_mont_felem_sqr(group, &gamma, &gamma);
+ ec_GFp_mont_felem_mul(group, &r->Y, &alpha, &r->Y);
+ ec_felem_add(group, &gamma, &gamma, &gamma);
+ ec_felem_sub(group, &r->Y, &r->Y, &gamma);
+ } else {
+ // The method is taken from:
+ // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-dbl-2007-bl
+ //
+ // Coq transcription and correctness proof:
+ // <https://github.com/davidben/fiat-crypto/blob/c7b95f62b2a54b559522573310e9b487327d219a/src/Curves/Weierstrass/Jacobian.v#L102>
+ // <https://github.com/davidben/fiat-crypto/blob/c7b95f62b2a54b559522573310e9b487327d219a/src/Curves/Weierstrass/Jacobian.v#L534>
+ EC_FELEM xx, yy, yyyy, zz;
+ ec_GFp_mont_felem_sqr(group, &xx, &a->X);
+ ec_GFp_mont_felem_sqr(group, &yy, &a->Y);
+ ec_GFp_mont_felem_sqr(group, &yyyy, &yy);
+ ec_GFp_mont_felem_sqr(group, &zz, &a->Z);
+
+ // s = 2*((x_in + yy)^2 - xx - yyyy)
+ EC_FELEM s;
+ ec_felem_add(group, &s, &a->X, &yy);
+ ec_GFp_mont_felem_sqr(group, &s, &s);
+ ec_felem_sub(group, &s, &s, &xx);
+ ec_felem_sub(group, &s, &s, &yyyy);
+ ec_felem_add(group, &s, &s, &s);
+
+ // m = 3*xx + a*zz^2
+ EC_FELEM m;
+ ec_GFp_mont_felem_sqr(group, &m, &zz);
+ ec_GFp_mont_felem_mul(group, &m, &group->a, &m);
+ ec_felem_add(group, &m, &m, &xx);
+ ec_felem_add(group, &m, &m, &xx);
+ ec_felem_add(group, &m, &m, &xx);
+
+ // x_out = m^2 - 2*s
+ ec_GFp_mont_felem_sqr(group, &r->X, &m);
+ ec_felem_sub(group, &r->X, &r->X, &s);
+ ec_felem_sub(group, &r->X, &r->X, &s);
+
+ // z_out = (y_in + z_in)^2 - yy - zz
+ ec_felem_add(group, &r->Z, &a->Y, &a->Z);
+ ec_GFp_mont_felem_sqr(group, &r->Z, &r->Z);
+ ec_felem_sub(group, &r->Z, &r->Z, &yy);
+ ec_felem_sub(group, &r->Z, &r->Z, &zz);
+
+ // y_out = m*(s-x_out) - 8*yyyy
+ ec_felem_add(group, &yyyy, &yyyy, &yyyy);
+ ec_felem_add(group, &yyyy, &yyyy, &yyyy);
+ ec_felem_add(group, &yyyy, &yyyy, &yyyy);
+ ec_felem_sub(group, &r->Y, &s, &r->X);
+ ec_GFp_mont_felem_mul(group, &r->Y, &r->Y, &m);
+ ec_felem_sub(group, &r->Y, &r->Y, &yyyy);
+ }
+}
+
+static int ec_GFp_mont_cmp_x_coordinate(const EC_GROUP *group,
+ const EC_JACOBIAN *p,
+ const EC_SCALAR *r) {
+ if (!group->field_greater_than_order ||
+ group->field.width != group->order.width) {
+ // Do not bother optimizing this case. p > order in all commonly-used
+ // curves.
+ return ec_GFp_simple_cmp_x_coordinate(group, p, r);
+ }
+
+ if (ec_GFp_simple_is_at_infinity(group, p)) {
+ return 0;
+ }
+
+ // We wish to compare X/Z^2 with r. This is equivalent to comparing X with
+ // r*Z^2. Note that X and Z are represented in Montgomery form, while r is
+ // not.
+ EC_FELEM r_Z2, Z2_mont, X;
+ ec_GFp_mont_felem_mul(group, &Z2_mont, &p->Z, &p->Z);
+ // r < order < p, so this is valid.
+ OPENSSL_memcpy(r_Z2.words, r->words, group->field.width * sizeof(BN_ULONG));
+ ec_GFp_mont_felem_mul(group, &r_Z2, &r_Z2, &Z2_mont);
+ ec_GFp_mont_felem_from_montgomery(group, &X, &p->X);
+
+ if (ec_felem_equal(group, &r_Z2, &X)) {
+ return 1;
+ }
+
+ // During signing the x coefficient is reduced modulo the group order.
+ // Therefore there is a small possibility, less than 1/2^128, that group_order
+ // < p.x < P. in that case we need not only to compare against |r| but also to
+ // compare against r+group_order.
+ if (bn_less_than_words(r->words, group->field_minus_order.words,
+ group->field.width)) {
+ // We can ignore the carry because: r + group_order < p < 2^256.
+ bn_add_words(r_Z2.words, r->words, group->order.d, group->field.width);
+ ec_GFp_mont_felem_mul(group, &r_Z2, &r_Z2, &Z2_mont);
+ if (ec_felem_equal(group, &r_Z2, &X)) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+DEFINE_METHOD_FUNCTION(EC_METHOD, EC_GFp_mont_method) {
+ out->group_init = ec_GFp_mont_group_init;
+ out->group_finish = ec_GFp_mont_group_finish;
+ out->group_set_curve = ec_GFp_mont_group_set_curve;
+ out->point_get_affine_coordinates = ec_GFp_mont_point_get_affine_coordinates;
+ out->jacobian_to_affine_batch = ec_GFp_mont_jacobian_to_affine_batch;
+ out->add = ec_GFp_mont_add;
+ out->dbl = ec_GFp_mont_dbl;
+ out->mul = ec_GFp_mont_mul;
+ out->mul_base = ec_GFp_mont_mul_base;
+ out->mul_batch = ec_GFp_mont_mul_batch;
+ out->mul_public_batch = ec_GFp_mont_mul_public_batch;
+ out->init_precomp = ec_GFp_mont_init_precomp;
+ out->mul_precomp = ec_GFp_mont_mul_precomp;
+ out->felem_mul = ec_GFp_mont_felem_mul;
+ out->felem_sqr = ec_GFp_mont_felem_sqr;
+ out->felem_to_bytes = ec_GFp_mont_felem_to_bytes;
+ out->felem_from_bytes = ec_GFp_mont_felem_from_bytes;
+ out->felem_reduce = ec_GFp_mont_felem_reduce;
+ out->felem_exp = ec_GFp_mont_felem_exp;
+ out->scalar_inv0_montgomery = ec_simple_scalar_inv0_montgomery;
+ out->scalar_to_montgomery_inv_vartime =
+ ec_simple_scalar_to_montgomery_inv_vartime;
+ out->cmp_x_coordinate = ec_GFp_mont_cmp_x_coordinate;
+}
diff --git a/src/crypto/fipsmodule/ec/ec_scalar_base_mult_tests.txt b/src/crypto/fipsmodule/ec/ec_scalar_base_mult_tests.txt
new file mode 100644
index 0000000..d48a021
--- /dev/null
+++ b/src/crypto/fipsmodule/ec/ec_scalar_base_mult_tests.txt
@@ -0,0 +1,3101 @@
+# This file contains multiples of the base point for various curves. The point
+# at infinity is represented as X = 0, Y = 0.
+#
+# This file is generated by make_ec_scalar_base_mult_tests.go
+
+Curve = P-224
+# N = -64
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c29fd
+X = d9174b3ca6b093dee706b10e1d90309aa58aebf6c9006a37f3716fde
+Y = 5091be99fda790ff9e6ecd2ac66b734f157f46402bf194d3bd8c194d
+
+Curve = P-224
+# N = -63
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c29fe
+X = 2e74dd665404a8900c8e3d4f822b7a9b6dcb64940ef5f5671caba7ef
+Y = f58bc45165c62d4c2c2ad7a8fb7e8f03322ce8ea5dc9c29f77625b14
+
+Curve = P-224
+# N = -62
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c29ff
+X = c671c49a40fdb37ee1afb59c55915461d0c4b2a67cbe4f1f0c747c97
+Y = 467fdfe495f8d2f97b00b4f8b83abdf40dc6c1b666fc5edc29225ed6
+
+Curve = P-224
+# N = -61
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a00
+X = 2396b9ee84e06252585475f54b390553185c05702db27913a80911b8
+Y = 5bb2feab11a9448a5a11ae2b51e4132f0da82d7866b1b971dd85edd2
+
+Curve = P-224
+# N = -60
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a01
+X = 8c64ebb538c109bbd60fd54cf7ff47216d30ecefbac0824c6e50b291
+Y = bfd6736f43c5ebb33959c9ec4444f5ea6c86e645b03dbed955ae402b
+
+Curve = P-224
+# N = -59
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a02
+X = 79fb86be63eed9cf12d44df82123ac91042f888b91b1b916bd3c107e
+Y = 4bac5537dc8a32199840b52e4c4002733b7941c69c711c8248e8e33e
+
+Curve = P-224
+# N = -58
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a03
+X = eb81ac109e13fe579100edba2dd5389945b3fdf247b4036b018acf60
+Y = 778b905f5bd3254728b9105ad7e4c53794201298b40d5fd166a75467
+
+Curve = P-224
+# N = -57
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a04
+X = 868ef00d187fef3010c81e77e214a828b4f9227cf5761d7eed89d916
+Y = dae0eef456786c9592faebd46cf44d711fe16fa66b63bf7e8f70d911
+
+Curve = P-224
+# N = -56
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a05
+X = 7cdfaa27e1972788b9891be32d4491c5a9f7187a05c7d40107b7f0fc
+Y = 46bb23e1eed098c6ac43e6c7e6a48c9e1e9c8169ef82488581f3782a
+
+Curve = P-224
+# N = -55
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a06
+X = a3168f507cc5ca03ec9507ff1fbe5ca00f3a1410948250749639b32a
+Y = 7d83b007949ca192bbd2a691c208fe5e0adacbee0d5bc807cfc44a9e
+
+Curve = P-224
+# N = -54
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a07
+X = e095d7363877c57e22ad1a708b7775ae804cceacecf2e2df16618035
+Y = b58fa951b3d1ce053b38a7cb072e69f64d281efc8cc9f1f42bbfde5e
+
+Curve = P-224
+# N = -53
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a08
+X = df5d3ed85b75fb433d057198debdd036cd9f11f339a4d607eb424932
+Y = a61a1c0ab289b7658439375678b7a2e99b0c292297dbedf22eb912e9
+
+Curve = P-224
+# N = -52
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a09
+X = 6e53e26a8b7b28a7c7a61dd4d53d509514edad71188245929589c788
+Y = f85f23a7c85fd7efc006d3eb13480eb0f6f647fdea5b59d06366d558
+
+Curve = P-224
+# N = -51
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a0a
+X = 5b4ce687825f6a00f83cd3bbc77c67dc14d91bd78d4e47f7e2ce7b0f
+Y = 6a86b2451d4be8409dec03799f680c806bc355e798591857fb8eddd6
+
+Curve = P-224
+# N = -50
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a0b
+X = bce605150a1d4d750c5a043fb4136726f99b4a41f35d3b3832ea583f
+Y = 768e2427050ad575667f8784b7fe8c6b2ae7873a7ff11ded64a13b0c
+
+Curve = P-224
+# N = -49
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a0c
+X = f18721e462d2340c4a88e00130d86691386ba2a83d1fb1dc8b927cca
+Y = b31f4d99a118d1c2c19f0815a89a921305d8d52005b64dd249b6a8e9
+
+Curve = P-224
+# N = -48
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a0d
+X = f087c8764bb082e669a8afbc5db571971898ccc2c5d4baf73cd35e9d
+Y = 72edb9b8154237917e7a05581d1cb2048d4d31c4ab90d005c9b67e4a
+
+Curve = P-224
+# N = -47
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a0e
+X = eca965fd046c7fd242e29ba1a178b71b1ec6e7af6a5b88232a285c92
+Y = 3e526a6b5ecbd24f9308de03fdb757a51a564ebc5872dbef7886cc7c
+
+Curve = P-224
+# N = -46
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a0f
+X = 71f8a2cdf405c7ee499dbd7216a07e5aa61b8faa4fd20b516d2761d4
+Y = 7a3008d5e50050b0ab427b36d15de75c0c190f7eb0b6a130106354f7
+
+Curve = P-224
+# N = -45
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a10
+X = cc96733b052b2f04f1cebb4cb8afb448a21c09821d6288b86cb8a17a
+Y = 159e86c0c38e8f7fc210036054941444c90054fd2047a4eb0dbdbc6e
+
+Curve = P-224
+# N = -44
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a11
+X = d20981b43d053ca0ca30994a5586e7f2342c479b07c6c367d0025900
+Y = 572b87044e041001d988793e9ae35378f7b9121a0d7abc1941b7cf8d
+
+Curve = P-224
+# N = -43
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a12
+X = 2f9a6dce655ee5d9f00b398e756defe1499b98df1e2edac8a784ad75
+Y = bd851fc17271dca923b803a4a4554a949bfc20f14f26feacc2649762
+
+Curve = P-224
+# N = -42
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a13
+X = 0a8b3acff07b4e49ed1d6cd0e8cebbb0ac9f5bc5ec7d65e0adf7b21c
+Y = 6aea047a1d6c9ea9df67e58538a8c88be591728e6c0d1443063199a4
+
+Curve = P-224
+# N = -41
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a14
+X = c772baaa90a968d497e0adbf116453e4f8c21c0acbea0ee34502317c
+Y = de20e75207355906ed957ac40260148fda74b9acf699fa06caf08a62
+
+Curve = P-224
+# N = -40
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a15
+X = 5e4cdfc6fc36ea0cd69a38a7485a317a0aeded6b5f6cd80072826385
+Y = 14afef7672ca22afe13292524ab55dfeef828e7e1e6abd8aadb9f27f
+
+Curve = P-224
+# N = -39
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a16
+X = 9a89bcce6f9b400618997c1184c5099a154a07954cb15d5c9f4492ca
+Y = f48eba6a110031e81a8e50a0c3e5c141e3a66d12ef040e2cd36c4fcd
+
+Curve = P-224
+# N = -38
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a17
+X = 68eee585a12332d41aef6f91a587bc3ca57329508fcc9f5bb3907516
+Y = df09fa68ba98511870b892e5f59c02792aed884376ecc9b081641901
+
+Curve = P-224
+# N = -37
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a18
+X = 9810b8218ec461154d317a954df66f5f81e51dc07ed7421b17d0b8aa
+Y = e166fda56ccb98bbfa8423bcacbcacc05ddac7e88ff0ce13c805a10a
+
+Curve = P-224
+# N = -36
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a19
+X = 6116976ec4511b1b9ee2b839378ff122c2bdb3f58823a82a68aef8e1
+Y = 99b4990881ca11762f616528685fbf94eb1708fa1ae25f010d070beb
+
+Curve = P-224
+# N = -35
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a1a
+X = da200dcda742573ca097e34bb87b356b84541f765cf38d2bf07471b0
+Y = ef05917f8f13fc686a8a0b6b544b0a1ed3488f1dff476a9a9c7cc19e
+
+Curve = P-224
+# N = -34
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a1b
+X = f8188c7623f76642286b8e9e4d4c5d58b8eaf7265b3b0e816076e7e4
+Y = bc6fc80b788a058da4873e54acc733db09105a6775bfb3faa6c549af
+
+Curve = P-224
+# N = -33
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a1c
+X = 224c4a62c8b1028606603cce1d451409b23d680bb063a8e6875d3b5c
+Y = ca97069c235efeb00a05729df91171d17605320950a1cea2e49fd119
+
+Curve = P-224
+# N = -32
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a1d
+X = b700a5c3bb6379de6caea37ff7a47ca909bec01a603c5ec5e1d1e794
+Y = 39e4c2c2e0968ef8a7cd7cabbfd37d0d2335579e72145109b23ce46a
+
+Curve = P-224
+# N = -31
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a1e
+X = 0ecf1b60836e92b7af968bccd69ff8300d55a42b0e855a4ff3546eab
+Y = 4bd76a3b0d1e95b063d22f890c68ebfd2327e3af12611c8f66bc1d21
+
+Curve = P-224
+# N = -30
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a1f
+X = 599b7e7e639bc335eb891295f0d8f4d8d8c76e588f0767741ab07558
+Y = a5aa7d10418290c0f35d3e4fccd02e4b3bc48ac8a87ad052e4cdcc14
+
+Curve = P-224
+# N = -29
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a20
+X = f63f9d855262e9b691f9bb848c78859508a8c1e6fb3246212e146e5c
+Y = f75d5db787bfb5cb199828b1040e7ccd9a20d198d9f82a81001cf9e4
+
+Curve = P-224
+# N = -28
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a21
+X = 1243a602d84f3ea7cf4a56f86ccb93395c1d609af98d6474d8e7afb1
+Y = 42c598ef4d24cb1f640cafc463a244dc4a26c694bf7b4737c8c6ec7c
+
+Curve = P-224
+# N = -27
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a22
+X = 1989153b5f6636b610854bcc50afc929e914c03da51a4a8239f4865b
+Y = 46c7e1923864a71fbbc324ff6e9b7c842baf5973e6e6d0ed9abd8695
+
+Curve = P-224
+# N = -26
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a23
+X = 263ed2217b1f0a813156e647e87e6cf618b9635c3f910f9d92153b04
+Y = ba1722401bfc9e41088cac3974d5ec7ad91fa0cd95b0a3555a23194a
+
+Curve = P-224
+# N = -25
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a24
+X = f1a7ae364dba054b51dff5d5ce16fb28965fb3777dca1ce3c1ad6ad0
+Y = b15ffa68153924545b397331387cee02f86c97f51fb4d28a172db95d
+
+Curve = P-224
+# N = -24
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a25
+X = affdfabc0525468041b2baf73874ec60762a670562c0248e474456a1
+Y = 00828bfdac88b772536123340be2bf21ccec9cda4e9ba00d50db9e30
+
+Curve = P-224
+# N = -23
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a26
+X = 2da9b6b6ec26e646ceef802c560782026da04bf2f2d196f4bca2d074
+Y = 58d6f33f99ff23e92c8a043b47b66ae89f7d30289b35b16aea963966
+
+Curve = P-224
+# N = -22
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a27
+X = c9bdd86f5fb7fe1e54c6ff9026f20add6c1984f1ef22b80a887af62c
+Y = eec590de16f168bde8d375e5dcc22402db091965c0a5bf7f95cf88f5
+
+Curve = P-224
+# N = -21
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a28
+X = a3d482c3e7eec18c534d4ceb1c9b8cefecb369a68a85a4e826165174
+Y = 9b11ffa67c105561b349cb872408dfdc8daf9071a39d9c38fee98408
+
+Curve = P-224
+# N = -20
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a29
+X = fcc7f2b45df1cd5a3c0c0731ca47a8af75cfb0347e8354eefe782455
+Y = f2a28eefd8b345832116f1e574f2c6b2c895aa8c24941f40d8b80ad1
+
+Curve = P-224
+# N = -19
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a2a
+X = a1e81c04f30ce201c7c9ace785ed44cc33b455a022f2acdbc6cae83c
+Y = 230e093c24f638f533dac6e2b6d01da3b5e7f45429315ca93fb8e634
+
+Curve = P-224
+# N = -18
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a2b
+X = c9ff61b040874c0568479216824a15eab1a838a797d189746226e4cc
+Y = 156729f1a003647030666054e208180f8f7b0df2249e44fba5931fff
+
+Curve = P-224
+# N = -17
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a2c
+X = b8357c3a6ceef288310e17b8bfeff9200846ca8c1942497c484403bc
+Y = 00eb610599f95942df1082e4f9426d086fb9c6231ae8b24933aab5db
+
+Curve = P-224
+# N = -16
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a2d
+X = 0b6ec4fe1777382404ef679997ba8d1cc5cd8e85349259f590c4c66d
+Y = cc662b9bcba6f94ee4ff1c9c10bd6ddd0d138df2d099a282152a4b7f
+
+Curve = P-224
+# N = -15
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a2e
+X = baa4d8635511a7d288aebeedd12ce529ff102c91f97f867e21916bf9
+Y = 6865a0b8a607f0b04b13d1cb0aa992a5a97f5ee8ca1849efb9ed8678
+
+Curve = P-224
+# N = -14
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a2f
+X = a53640c83dc208603ded83e4ecf758f24c357d7cf48088b2ce01e9fa
+Y = 2a7eb328dbe663b5a468b5bc97a040a3745396ba636b964370dc3352
+
+Curve = P-224
+# N = -13
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a30
+X = 34e8e17a430e43289793c383fac9774247b40e9ebd3366981fcfaeca
+Y = dad7e608e380480434ea641cc82c82cbc92801469c8db0204f13489a
+
+Curve = P-224
+# N = -12
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a31
+X = 6e31ee1dc137f81b056752e4deab1443a481033e9b4c93a3044f4f7a
+Y = df82220fc7a4021549165325725f94c3410ddb56c54e161fc9ef62ee
+
+Curve = P-224
+# N = -11
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a32
+X = ef53b6294aca431f0f3c22dc82eb9050324f1d88d377e716448e507c
+Y = df4aefffbf6d1699c930481cd102127c9a3d992048ab05929b6e5927
+
+Curve = P-224
+# N = -10
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a33
+X = aea9e17a306517eb89152aa7096d2c381ec813c51aa880e7bee2c0fd
+Y = c644cf154cc81f5ade49345e541b4d4b5c1adb3eb5c01c14ee949aa2
+
+Curve = P-224
+# N = -9
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a34
+X = 2fdcccfee720a77ef6cb3bfbb447f9383117e3daa4a07e36ed15f78d
+Y = c8e8cd1b0be40b0877cfca1958603122f1e6914f84b7e8e968ae8b9e
+
+Curve = P-224
+# N = -8
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a35
+X = 858e6f9cc6c12c31f5df124aa77767b05c8bc021bd683d2b55571550
+Y = fb9232c15a3bc7673a3a03b0253824c53d0fd1411b1cabe2e187fb87
+
+Curve = P-224
+# N = -7
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a36
+X = db2f6be630e246a5cf7d99b85194b123d487e2d466b94b24a03c3e28
+Y = f0c5cff7ab680d09ee11dae84e9c1072ac48ea2e744b1b7f72fd469e
+
+Curve = P-224
+# N = -6
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a37
+X = 1f2483f82572251fca975fea40db821df8ad82a3c002ee6c57112408
+Y = 76050f3348af2664aac3a8b05281304ebc7a7914c6ad50a4b4eac383
+
+Curve = P-224
+# N = -5
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a38
+X = 31c49ae75bce7807cdff22055d94ee9021fedbb5ab51c57526f011aa
+Y = d817400e8ba9ca13a45f360e3d121eaaeb39af82d6001c8186f5f866
+
+Curve = P-224
+# N = -4
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a39
+X = ae99feebb5d26945b54892092a8aee02912930fa41cd114e40447301
+Y = fb7da7f5f13a43b81774373c879cd32d6934c05fa758eeb14fcfab38
+
+Curve = P-224
+# N = -3
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3a
+X = df1b1d66a551d0d31eff822558b9d2cc75c2180279fe0d08fd896d04
+Y = 5c080fc3522f41bbb3f55a97cfecf21f882ce8cbb1e50ca6e67e56dc
+
+Curve = P-224
+# N = -2
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3b
+X = 706a46dc76dcb76798e60e6d89474788d16dc18032d268fd1a704fa6
+Y = e3d4895843da188fd58fb0567976d7b50359d6b78530c8f62d1b1746
+
+Curve = P-224
+# N = -1
+N = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3c
+X = b70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21
+Y = 42c89c774a08dc04b3dd201932bc8a5ea5f8b89bbb2a7e667aff81cd
+
+Curve = P-224
+# N = 0
+N = 00000000000000000000000000000000000000000000000000000000
+X = 00000000000000000000000000000000000000000000000000000000
+Y = 00000000000000000000000000000000000000000000000000000000
+
+Curve = P-224
+# N = 1
+N = 00000000000000000000000000000000000000000000000000000001
+X = b70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21
+Y = bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34
+
+Curve = P-224
+# N = 2
+N = 00000000000000000000000000000000000000000000000000000002
+X = 706a46dc76dcb76798e60e6d89474788d16dc18032d268fd1a704fa6
+Y = 1c2b76a7bc25e7702a704fa986892849fca629487acf3709d2e4e8bb
+
+Curve = P-224
+# N = 3
+N = 00000000000000000000000000000000000000000000000000000003
+X = df1b1d66a551d0d31eff822558b9d2cc75c2180279fe0d08fd896d04
+Y = a3f7f03cadd0be444c0aa56830130ddf77d317344e1af3591981a925
+
+Curve = P-224
+# N = 4
+N = 00000000000000000000000000000000000000000000000000000004
+X = ae99feebb5d26945b54892092a8aee02912930fa41cd114e40447301
+Y = 0482580a0ec5bc47e88bc8c378632cd196cb3fa058a7114eb03054c9
+
+Curve = P-224
+# N = 5
+N = 00000000000000000000000000000000000000000000000000000005
+X = 31c49ae75bce7807cdff22055d94ee9021fedbb5ab51c57526f011aa
+Y = 27e8bff1745635ec5ba0c9f1c2ede15414c6507d29ffe37e790a079b
+
+Curve = P-224
+# N = 6
+N = 00000000000000000000000000000000000000000000000000000006
+X = 1f2483f82572251fca975fea40db821df8ad82a3c002ee6c57112408
+Y = 89faf0ccb750d99b553c574fad7ecfb0438586eb3952af5b4b153c7e
+
+Curve = P-224
+# N = 7
+N = 00000000000000000000000000000000000000000000000000000007
+X = db2f6be630e246a5cf7d99b85194b123d487e2d466b94b24a03c3e28
+Y = 0f3a30085497f2f611ee2517b163ef8c53b715d18bb4e4808d02b963
+
+Curve = P-224
+# N = 8
+N = 00000000000000000000000000000000000000000000000000000008
+X = 858e6f9cc6c12c31f5df124aa77767b05c8bc021bd683d2b55571550
+Y = 046dcd3ea5c43898c5c5fc4fdac7db39c2f02ebee4e3541d1e78047a
+
+Curve = P-224
+# N = 9
+N = 00000000000000000000000000000000000000000000000000000009
+X = 2fdcccfee720a77ef6cb3bfbb447f9383117e3daa4a07e36ed15f78d
+Y = 371732e4f41bf4f7883035e6a79fcedc0e196eb07b48171697517463
+
+Curve = P-224
+# N = 10
+N = 0000000000000000000000000000000000000000000000000000000a
+X = aea9e17a306517eb89152aa7096d2c381ec813c51aa880e7bee2c0fd
+Y = 39bb30eab337e0a521b6cba1abe4b2b3a3e524c14a3fe3eb116b655f
+
+Curve = P-224
+# N = 11
+N = 0000000000000000000000000000000000000000000000000000000b
+X = ef53b6294aca431f0f3c22dc82eb9050324f1d88d377e716448e507c
+Y = 20b510004092e96636cfb7e32efded8265c266dfb754fa6d6491a6da
+
+Curve = P-224
+# N = 12
+N = 0000000000000000000000000000000000000000000000000000000c
+X = 6e31ee1dc137f81b056752e4deab1443a481033e9b4c93a3044f4f7a
+Y = 207dddf0385bfdeab6e9acda8da06b3bbef224a93ab1e9e036109d13
+
+Curve = P-224
+# N = 13
+N = 0000000000000000000000000000000000000000000000000000000d
+X = 34e8e17a430e43289793c383fac9774247b40e9ebd3366981fcfaeca
+Y = 252819f71c7fb7fbcb159be337d37d3336d7feb963724fdfb0ecb767
+
+Curve = P-224
+# N = 14
+N = 0000000000000000000000000000000000000000000000000000000e
+X = a53640c83dc208603ded83e4ecf758f24c357d7cf48088b2ce01e9fa
+Y = d5814cd724199c4a5b974a43685fbf5b8bac69459c9469bc8f23ccaf
+
+Curve = P-224
+# N = 15
+N = 0000000000000000000000000000000000000000000000000000000f
+X = baa4d8635511a7d288aebeedd12ce529ff102c91f97f867e21916bf9
+Y = 979a5f4759f80f4fb4ec2e34f5566d595680a11735e7b61046127989
+
+Curve = P-224
+# N = 16
+N = 00000000000000000000000000000000000000000000000000000010
+X = 0b6ec4fe1777382404ef679997ba8d1cc5cd8e85349259f590c4c66d
+Y = 3399d464345906b11b00e363ef429221f2ec720d2f665d7dead5b482
+
+Curve = P-224
+# N = 17
+N = 00000000000000000000000000000000000000000000000000000011
+X = b8357c3a6ceef288310e17b8bfeff9200846ca8c1942497c484403bc
+Y = ff149efa6606a6bd20ef7d1b06bd92f6904639dce5174db6cc554a26
+
+Curve = P-224
+# N = 18
+N = 00000000000000000000000000000000000000000000000000000012
+X = c9ff61b040874c0568479216824a15eab1a838a797d189746226e4cc
+Y = ea98d60e5ffc9b8fcf999fab1df7e7ef7084f20ddb61bb045a6ce002
+
+Curve = P-224
+# N = 19
+N = 00000000000000000000000000000000000000000000000000000013
+X = a1e81c04f30ce201c7c9ace785ed44cc33b455a022f2acdbc6cae83c
+Y = dcf1f6c3db09c70acc25391d492fe25b4a180babd6cea356c04719cd
+
+Curve = P-224
+# N = 20
+N = 00000000000000000000000000000000000000000000000000000014
+X = fcc7f2b45df1cd5a3c0c0731ca47a8af75cfb0347e8354eefe782455
+Y = 0d5d7110274cba7cdee90e1a8b0d394c376a5573db6be0bf2747f530
+
+Curve = P-224
+# N = 21
+N = 00000000000000000000000000000000000000000000000000000015
+X = a3d482c3e7eec18c534d4ceb1c9b8cefecb369a68a85a4e826165174
+Y = 64ee005983efaa9e4cb63478dbf7202272506f8e5c6263c701167bf9
+
+Curve = P-224
+# N = 22
+N = 00000000000000000000000000000000000000000000000000000016
+X = c9bdd86f5fb7fe1e54c6ff9026f20add6c1984f1ef22b80a887af62c
+Y = 113a6f21e90e9742172c8a1a233ddbfc24f6e69a3f5a40806a30770c
+
+Curve = P-224
+# N = 23
+N = 00000000000000000000000000000000000000000000000000000017
+X = 2da9b6b6ec26e646ceef802c560782026da04bf2f2d196f4bca2d074
+Y = a7290cc06600dc16d375fbc4b84995166082cfd764ca4e951569c69b
+
+Curve = P-224
+# N = 24
+N = 00000000000000000000000000000000000000000000000000000018
+X = affdfabc0525468041b2baf73874ec60762a670562c0248e474456a1
+Y = ff7d74025377488dac9edccbf41d40dd33136325b1645ff2af2461d1
+
+Curve = P-224
+# N = 25
+N = 00000000000000000000000000000000000000000000000000000019
+X = f1a7ae364dba054b51dff5d5ce16fb28965fb3777dca1ce3c1ad6ad0
+Y = 4ea00597eac6dbaba4c68ccec78311fc0793680ae04b2d75e8d246a4
+
+Curve = P-224
+# N = 26
+N = 0000000000000000000000000000000000000000000000000000001a
+X = 263ed2217b1f0a813156e647e87e6cf618b9635c3f910f9d92153b04
+Y = 45e8ddbfe40361bef77353c68b2a138426e05f326a4f5caaa5dce6b7
+
+Curve = P-224
+# N = 27
+N = 0000000000000000000000000000000000000000000000000000001b
+X = 1989153b5f6636b610854bcc50afc929e914c03da51a4a8239f4865b
+Y = b9381e6dc79b58e0443cdb009164837ad450a68c19192f126542796c
+
+Curve = P-224
+# N = 28
+N = 0000000000000000000000000000000000000000000000000000001c
+X = 1243a602d84f3ea7cf4a56f86ccb93395c1d609af98d6474d8e7afb1
+Y = bd3a6710b2db34e09bf3503b9c5dbb22b5d9396b4084b8c837391385
+
+Curve = P-224
+# N = 29
+N = 0000000000000000000000000000000000000000000000000000001d
+X = f63f9d855262e9b691f9bb848c78859508a8c1e6fb3246212e146e5c
+Y = 08a2a24878404a34e667d74efbf1833165df2e672607d57effe3061d
+
+Curve = P-224
+# N = 30
+N = 0000000000000000000000000000000000000000000000000000001e
+X = 599b7e7e639bc335eb891295f0d8f4d8d8c76e588f0767741ab07558
+Y = 5a5582efbe7d6f3f0ca2c1b0332fd1b3c43b753757852fad1b3233ed
+
+Curve = P-224
+# N = 31
+N = 0000000000000000000000000000000000000000000000000000001f
+X = 0ecf1b60836e92b7af968bccd69ff8300d55a42b0e855a4ff3546eab
+Y = b42895c4f2e16a4f9c2dd076f3971401dcd81c50ed9ee3709943e2e0
+
+Curve = P-224
+# N = 32
+N = 00000000000000000000000000000000000000000000000000000020
+X = b700a5c3bb6379de6caea37ff7a47ca909bec01a603c5ec5e1d1e794
+Y = c61b3d3d1f69710758328354402c82f1dccaa8618debaef64dc31b97
+
+Curve = P-224
+# N = 33
+N = 00000000000000000000000000000000000000000000000000000021
+X = 224c4a62c8b1028606603cce1d451409b23d680bb063a8e6875d3b5c
+Y = 3568f963dca1014ff5fa8d6206ee8e2d89facdf6af5e315d1b602ee8
+
+Curve = P-224
+# N = 34
+N = 00000000000000000000000000000000000000000000000000000022
+X = f8188c7623f76642286b8e9e4d4c5d58b8eaf7265b3b0e816076e7e4
+Y = 439037f48775fa725b78c1ab5338cc23f6efa5988a404c05593ab652
+
+Curve = P-224
+# N = 35
+N = 00000000000000000000000000000000000000000000000000000023
+X = da200dcda742573ca097e34bb87b356b84541f765cf38d2bf07471b0
+Y = 10fa6e8070ec03979575f494abb4f5e02cb770e200b8956563833e63
+
+Curve = P-224
+# N = 36
+N = 00000000000000000000000000000000000000000000000000000024
+X = 6116976ec4511b1b9ee2b839378ff122c2bdb3f58823a82a68aef8e1
+Y = 664b66f77e35ee89d09e9ad797a0406a14e8f705e51da0fef2f8f416
+
+Curve = P-224
+# N = 37
+N = 00000000000000000000000000000000000000000000000000000025
+X = 9810b8218ec461154d317a954df66f5f81e51dc07ed7421b17d0b8aa
+Y = 1e99025a93346744057bdc435343533ea2253817700f31ec37fa5ef7
+
+Curve = P-224
+# N = 38
+N = 00000000000000000000000000000000000000000000000000000026
+X = 68eee585a12332d41aef6f91a587bc3ca57329508fcc9f5bb3907516
+Y = 20f605974567aee78f476d1a0a63fd85d51277bc8913364f7e9be700
+
+Curve = P-224
+# N = 39
+N = 00000000000000000000000000000000000000000000000000000027
+X = 9a89bcce6f9b400618997c1184c5099a154a07954cb15d5c9f4492ca
+Y = 0b714595eeffce17e571af5f3c1a3ebd1c5992ed10fbf1d32c93b034
+
+Curve = P-224
+# N = 40
+N = 00000000000000000000000000000000000000000000000000000028
+X = 5e4cdfc6fc36ea0cd69a38a7485a317a0aeded6b5f6cd80072826385
+Y = eb5010898d35dd501ecd6dadb54aa200107d7181e195427552460d82
+
+Curve = P-224
+# N = 41
+N = 00000000000000000000000000000000000000000000000000000029
+X = c772baaa90a968d497e0adbf116453e4f8c21c0acbea0ee34502317c
+Y = 21df18adf8caa6f9126a853bfd9feb6f258b4653096605f9350f759f
+
+Curve = P-224
+# N = 42
+N = 0000000000000000000000000000000000000000000000000000002a
+X = 0a8b3acff07b4e49ed1d6cd0e8cebbb0ac9f5bc5ec7d65e0adf7b21c
+Y = 9515fb85e293615620981a7ac75737731a6e8d7193f2ebbcf9ce665d
+
+Curve = P-224
+# N = 43
+N = 0000000000000000000000000000000000000000000000000000002b
+X = 2f9a6dce655ee5d9f00b398e756defe1499b98df1e2edac8a784ad75
+Y = 427ae03e8d8e2356dc47fc5b5baab56a6403df0eb0d901533d9b689f
+
+Curve = P-224
+# N = 44
+N = 0000000000000000000000000000000000000000000000000000002c
+X = d20981b43d053ca0ca30994a5586e7f2342c479b07c6c367d0025900
+Y = a8d478fbb1fbeffe267786c1651cac860846ede5f28543e6be483074
+
+Curve = P-224
+# N = 45
+N = 0000000000000000000000000000000000000000000000000000002d
+X = cc96733b052b2f04f1cebb4cb8afb448a21c09821d6288b86cb8a17a
+Y = ea61793f3c7170803deffc9fab6bebba36ffab02dfb85b14f2424393
+
+Curve = P-224
+# N = 46
+N = 0000000000000000000000000000000000000000000000000000002e
+X = 71f8a2cdf405c7ee499dbd7216a07e5aa61b8faa4fd20b516d2761d4
+Y = 85cff72a1affaf4f54bd84c92ea218a2f3e6f0814f495ecfef9cab0a
+
+Curve = P-224
+# N = 47
+N = 0000000000000000000000000000000000000000000000000000002f
+X = eca965fd046c7fd242e29ba1a178b71b1ec6e7af6a5b88232a285c92
+Y = c1ad9594a1342db06cf721fc0248a859e5a9b143a78d241087793385
+
+Curve = P-224
+# N = 48
+N = 00000000000000000000000000000000000000000000000000000030
+X = f087c8764bb082e669a8afbc5db571971898ccc2c5d4baf73cd35e9d
+Y = 8d124647eabdc86e8185faa7e2e34dfa72b2ce3b546f2ffa364981b7
+
+Curve = P-224
+# N = 49
+N = 00000000000000000000000000000000000000000000000000000031
+X = f18721e462d2340c4a88e00130d86691386ba2a83d1fb1dc8b927cca
+Y = 4ce0b2665ee72e3d3e60f7ea57656debfa272adffa49b22db6495718
+
+Curve = P-224
+# N = 50
+N = 00000000000000000000000000000000000000000000000000000032
+X = bce605150a1d4d750c5a043fb4136726f99b4a41f35d3b3832ea583f
+Y = 8971dbd8faf52a8a9980787b48017393d51878c5800ee2129b5ec4f5
+
+Curve = P-224
+# N = 51
+N = 00000000000000000000000000000000000000000000000000000033
+X = 5b4ce687825f6a00f83cd3bbc77c67dc14d91bd78d4e47f7e2ce7b0f
+Y = 95794dbae2b417bf6213fc866097f37e943caa1867a6e7a80471222b
+
+Curve = P-224
+# N = 52
+N = 00000000000000000000000000000000000000000000000000000034
+X = 6e53e26a8b7b28a7c7a61dd4d53d509514edad71188245929589c788
+Y = 07a0dc5837a028103ff92c14ecb7f14e0909b80215a4a62f9c992aa9
+
+Curve = P-224
+# N = 53
+N = 00000000000000000000000000000000000000000000000000000035
+X = df5d3ed85b75fb433d057198debdd036cd9f11f339a4d607eb424932
+Y = 59e5e3f54d76489a7bc6c8a987485d1564f3d6dd6824120dd146ed18
+
+Curve = P-224
+# N = 54
+N = 00000000000000000000000000000000000000000000000000000036
+X = e095d7363877c57e22ad1a708b7775ae804cceacecf2e2df16618035
+Y = 4a7056ae4c2e31fac4c75834f8d19608b2d7e10373360e0bd44021a3
+
+Curve = P-224
+# N = 55
+N = 00000000000000000000000000000000000000000000000000000037
+X = a3168f507cc5ca03ec9507ff1fbe5ca00f3a1410948250749639b32a
+Y = 827c4ff86b635e6d442d596e3df701a0f5253411f2a437f8303bb563
+
+Curve = P-224
+# N = 56
+N = 00000000000000000000000000000000000000000000000000000038
+X = 7cdfaa27e1972788b9891be32d4491c5a9f7187a05c7d40107b7f0fc
+Y = b944dc1e112f673953bc1938195b7360e1637e96107db77a7e0c87d7
+
+Curve = P-224
+# N = 57
+N = 00000000000000000000000000000000000000000000000000000039
+X = 868ef00d187fef3010c81e77e214a828b4f9227cf5761d7eed89d916
+Y = 251f110ba987936a6d05142b930bb28de01e9059949c4081708f26f0
+
+Curve = P-224
+# N = 58
+N = 0000000000000000000000000000000000000000000000000000003a
+X = eb81ac109e13fe579100edba2dd5389945b3fdf247b4036b018acf60
+Y = 88746fa0a42cdab8d746efa5281b3ac76bdfed674bf2a02e9958ab9a
+
+Curve = P-224
+# N = 59
+N = 0000000000000000000000000000000000000000000000000000003b
+X = 79fb86be63eed9cf12d44df82123ac91042f888b91b1b916bd3c107e
+Y = b453aac82375cde667bf4ad1b3bffd8bc486be39638ee37db7171cc3
+
+Curve = P-224
+# N = 60
+N = 0000000000000000000000000000000000000000000000000000003c
+X = 8c64ebb538c109bbd60fd54cf7ff47216d30ecefbac0824c6e50b291
+Y = 40298c90bc3a144cc6a63613bbbb0a14937919ba4fc24126aa51bfd6
+
+Curve = P-224
+# N = 61
+N = 0000000000000000000000000000000000000000000000000000003d
+X = 2396b9ee84e06252585475f54b390553185c05702db27913a80911b8
+Y = a44d0154ee56bb75a5ee51d4ae1beccff257d287994e468e227a122f
+
+Curve = P-224
+# N = 62
+N = 0000000000000000000000000000000000000000000000000000003e
+X = c671c49a40fdb37ee1afb59c55915461d0c4b2a67cbe4f1f0c747c97
+Y = b980201b6a072d0684ff4b0747c5420af2393e499903a123d6dda12b
+
+Curve = P-224
+# N = 63
+N = 0000000000000000000000000000000000000000000000000000003f
+X = 2e74dd665404a8900c8e3d4f822b7a9b6dcb64940ef5f5671caba7ef
+Y = 0a743bae9a39d2b3d3d52857048170fbcdd31715a2363d60889da4ed
+
+Curve = P-224
+# N = 64
+N = 00000000000000000000000000000000000000000000000000000040
+X = d9174b3ca6b093dee706b10e1d90309aa58aebf6c9006a37f3716fde
+Y = af6e416602586f00619132d539948cafea80b9bfd40e6b2c4273e6b4
+
+Curve = P-256
+# N = -64
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632511
+X = 0a0643fb8fcc14def67a6a5eb1bf8e9125b35edc7338d816aa4110a6b90ee785
+Y = aacbc7ccb56186ab3adf25325d6df18ff25ef30018fed128453f2eff79e0633d
+
+Curve = P-256
+# N = -63
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632512
+X = 6a9501d85bf5dc802a1f28a08acc7d8fdf53c8af01a7cd3832a290825d8bdac1
+Y = 359bf52d6cb8c8bd7e39391bb5c3a95c07b9e4a4968590cacf500ac2a0e10e5c
+
+Curve = P-256
+# N = -62
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632513
+X = 571c05c84021edcec4b1ac999829ecd80f8216b239c67f269f88ff57ae8cce2b
+Y = 06cda502e8accde7d204c260cfa0b6650033f3085944d22453fed73d7b547eea
+
+Curve = P-256
+# N = -61
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632514
+X = 059ccb19edd3da9a2d3a6b3d8d9900013e7910a08b724fd55939ac380d32af0e
+Y = 44952812352b6ea7259ad7e46cba9c71e9de085dc6a931326d71e1c368016e2e
+
+Curve = P-256
+# N = -60
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632515
+X = 05dae8c2c5a5afba7e53b9efcac1d0b8224559146918d320879bb82d96ef4963
+Y = 44f85bb1fc3f7ee71d087d2f28fcfb310d6617fe2e2c409da96fdc9fae2cbcdb
+
+Curve = P-256
+# N = -59
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632516
+X = 665f1a6ffe0c6437765b2784fca9bdf7e50941119e8dc8eca2b6ea0e0faa4b45
+Y = b6f1d35a6002e73e917335d608153c8082121a417e1dea4391da599fd480b330
+
+Curve = P-256
+# N = -58
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632517
+X = ec247d216208539a58912acd04d6df1f8b0b3c9affdc599e9e2481f254419b1d
+Y = 35ce35beb4dacb8bb916c4998a6a5a22038ea1cf25ce0a67d46ef9d9c53be021
+
+Curve = P-256
+# N = -57
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632518
+X = c116e30ebb4d2865126d45a8ea907f86289d406e2d6c6bd88abd97b1d0f56077
+Y = 16b877db3ca4cf3e474e92644ec4789a82a42a1861a6373acec028025bef3df9
+
+Curve = P-256
+# N = -56
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632519
+X = 6f9a14fbbcf2815a42e8b595d0d5a0eb956463496f67dc0d60a7520a83fb632e
+Y = 37bd614684bfb0d67ab3d21b3889362462780d4822c6b5a46d28a25d0db130d6
+
+Curve = P-256
+# N = -55
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63251a
+X = 079dba7ba068c9267571a109fe7fea2cc2a595b762c1eadadec1dff7df6e60a0
+Y = 23e1e647bc2b2e7fe2ddc062d56a77547c14d20da8ae5c6804f25a514b7db215
+
+Curve = P-256
+# N = -54
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63251b
+X = 6fc0cd2131b9eb0587c40153ae03fcc8f4b7dbe02cdc59fa4aa8b7d7c3a3dc7d
+Y = 2b4889e69b94faed3f1627c40c89ba9e539cf572caf4517a84f9a4e8ce021d5b
+
+Curve = P-256
+# N = -53
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63251c
+X = 6f01bd49c9d952455a47802254b88039982b1ca78de9b983f126ec9f7449d036
+Y = ea9df7ef0e2a2155ee5f0de59f788931587aae413c8b64f7c9fdcc226761e824
+
+Curve = P-256
+# N = -52
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63251d
+X = 194e35c4ec2f25ef537105d2b2e54c1803eb2d0a04492e3d2e1d72d04b978b18
+Y = 50bd98643eb15868424870e97c3bd6b3971582ef17c2a9643fb601dbfc30b89b
+
+Curve = P-256
+# N = -51
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63251e
+X = 672c4a514d9de43eaadee6863c1d68bc95f7eb56e81008ff044360f0018e22b1
+Y = ab73816d695da4029ee21a5b531dfc08ec9db9a868fb26be66cac66e6e0c8efb
+
+Curve = P-256
+# N = -50
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63251f
+X = ba6821cba9bab3ba57a98127482a5de00c108a6ac3241ebb508c58a24d9edba2
+Y = 77be3a209f3b50c578c8a1387342de1818f57ad7d28814b070de74fc987b1edf
+
+Curve = P-256
+# N = -49
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632520
+X = f785b0e098068875bb22b146866e6c0528fb7ea9758fd4fd7d228ce6a5674455
+Y = 8c024f3f9f7f25921ea38980f260a4beb4fb4903a0c559f51843b6f3ef29dbf7
+
+Curve = P-256
+# N = -48
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632521
+X = 9482fb0e492539ec8cce745be070cda11c2e92960a201a61abfb9dc69e4536ca
+Y = cae26357ba0ea807e5a29c7358acb19c09c2a1d7a8f84044e05279c40a733e37
+
+Curve = P-256
+# N = -47
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632522
+X = 42c315cc48958708595361ea83071bbcdd5b31583e19066d51d689227b1c0d7c
+Y = 9b659e30a8e46a7bd6eb2e204485866f8b0e5e1f14780e9b293b58d44d064e46
+
+Curve = P-256
+# N = -46
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632523
+X = b1bb852cfea701fc42caaa1a5b5eb6a5174e94f87c4d3b0612b46293eb5925f8
+Y = e2cc823893878b35b9fb82df902e1932df8a6872f610e8b087c15e067421c34f
+
+Curve = P-256
+# N = -45
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632524
+X = a891d06670bde99b3ecd0f5ddff0672e0f5f609edd29d6d979c78080fae0ba03
+Y = 4a69326cd3405e3fbe65773bfcc3e318e394c710014f0d33103c1237e996cb51
+
+Curve = P-256
+# N = -44
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632525
+X = 4756686a0d7e11cb04211f7813b498c2170bff9af47aab0e652d0380ac8d4f9b
+Y = 31ccb023ab79c591d003da70cb8b3b149a8aa55ac7b76f4bf17db5677d087a2f
+
+Curve = P-256
+# N = -43
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632526
+X = 986ae2506f1ff104d04230861d8f4b498f4bc4c6d009b30f7544dc129b82d28d
+Y = ffc3333e59b9f1f61cd75b2682c3849e279039d863e760dadaeef3bbe44f8168
+
+Curve = P-256
+# N = -42
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632527
+X = 6780c5fc70275e2c7061a0e7877bb174deadeb9887027f3fa83654158ba7f50c
+Y = c34573ca43ca2df27e08cf53e38429299e56bd07f395635aa3aed061b5ffed99
+
+Curve = P-256
+# N = -41
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632528
+X = 67a6bec240dee0651cf258d2e6cfe8aa6067c5c3d4175a593a7de694995d2fa2
+Y = 2196d48edd2ecea893db64b6b9b2bb66eabd3812df653593b63db31ebbe0112a
+
+Curve = P-256
+# N = -40
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632529
+X = bea01e7daad46131bd5b18584d0ee0c457b44d35ae412c0faa74b4da1aac91e6
+Y = de122b18f6b253fb277d212d7e942509ef0460e6d6922326cb38009bce2ae2e3
+
+Curve = P-256
+# N = -39
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63252a
+X = 22a682f7c3996d4d42014976a179046e547b942dd2d138d4a0c199ddfb2776c4
+Y = b0b9f94eefdddc1246e7367ca5abca93686233cffd9a4f97acb809b63455d7a2
+
+Curve = P-256
+# N = -38
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63252b
+X = 971581bdd1356ea1b317d7b29059611176788153b4d38f8d81155d60576d8c46
+Y = 78f3174f20f2a63f622ad0e179abe7955517bcbae7c0cdac7f387b1cd4313a6d
+
+Curve = P-256
+# N = -37
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63252c
+X = 419a6a646ddb817dd6b0978611a826aae0d21379246bfd4473a92894502b3348
+Y = ccdabb2feefd0a7caba3604e6ab3d02aec392f8e0c211e1d24e2937e4f6deb4d
+
+Curve = P-256
+# N = -36
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63252d
+X = da5bd2d111c3731d14281d73d5e965a384e94cbf9664dc227d2a45b9abb598ef
+Y = 9e9903e5c70f93acddb9ad84f8a206dd44ea6da8e84bd95b6dccc3dbdfbb51a0
+
+Curve = P-256
+# N = -35
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63252e
+X = d58d4a589ed27d168ffa3ad7326c48ca94e8e1fe92af9700a12d389033bb291a
+Y = 2baaeb2dfd8d947b89156d9cd238010998d8e3eac4fcb6865a4f36390a79462a
+
+Curve = P-256
+# N = -34
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63252f
+X = 2f9e6ebf717def118d1a092fce97133919cf2d31b7f8be6cfb7fdbe16820999e
+Y = 85115526acd077df1c34e5eb2f0adb09e97d2d6bf51215f28a9477fcf941f4d0
+
+Curve = P-256
+# N = -33
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632530
+X = 9807d699fcd81356fa9aa25b89d9d34ea03b0a533aa872fd65c100f3cb2cd793
+Y = 3d5a6322354ee40e795fe5b2e2f6e4d00019cf4793a787acd09406db869cb50b
+
+Curve = P-256
+# N = -32
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632531
+X = 2377c7d690a242ca6c45074e8ea5beefaa557fd5b68371d9d1475bd52a7ed0e1
+Y = b85ec0457bec5bc7c0726f16406fe48199a75933130b98e9183f984e22472d4d
+
+Curve = P-256
+# N = -31
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632532
+X = 301d9e502dc7e05da85da026a7ae9aa0fac9db7d52a95b3e3e3f9aa0a1b45b8b
+Y = 9aae49084cf9eddd1f2dc3fd94fe828dd672651c9778359e2a7249515e811d98
+
+Curve = P-256
+# N = -30
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632533
+X = 409f8da21aea236a5f5a1904d0310c1c6192a67d0da08936319869a8ad0838a3
+Y = 8f23084d30ff71a9f1d918d42c42bf08c1665f14e9d5986c1e9c2d38d5e170a5
+
+Curve = P-256
+# N = -29
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632534
+X = d6d33adefa195b07a7c36da090853b8cfd8cd1c688b58a41dedd693d1c784def
+Y = 7b5545e811e6a282c087dba0aa75a234f65e9955b46a1212aaf3edba6c2e4359
+
+Curve = P-256
+# N = -28
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632535
+X = 38d86fa55b4fd1586c5f05fae7acfc4d36cbdcf7fa62129339246f69c4300e4e
+Y = c06c47a4b542f0d980095976f618fdd1074603456e276448606cf23f00961b84
+
+Curve = P-256
+# N = -27
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632536
+X = 184ffa5819d80d51deba2fac4611f378576355bd683e54abf2e201173b0883d1
+Y = 3f5991d799770ca75b3926f7d934666aba4213349c0fb6e9df2dbd3d9f6f9190
+
+Curve = P-256
+# N = -26
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632537
+X = f5757c012185a599d1f3958b0ae68aa5dffd3d78e1a2eee67417001857658331
+Y = c6c5912ed3898a4eb4edc72e2d5f702af591a1aff7207bf400acc2018d97213b
+
+Curve = P-256
+# N = -25
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632538
+X = 3a67e2554b0c0bb685f4f52d8c07fa8441652fc5b76f1b2484a4dc45f200d687
+Y = d82f0e77d0e030bdd9250d98e9c504f273e77509ca589e755612e94cfd086cdb
+
+Curve = P-256
+# N = -24
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632539
+X = db474918ec62ad7eb652b8b0af585aba9b2f394723ab103776e27d7d8c2aa4cb
+Y = 7a7ee2c5448bc0d8bc686b9f84f92ad475db63b97cf5c82dde249a936b5854aa
+
+Curve = P-256
+# N = -23
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63253a
+X = 0e91c7239c2640d7d28a3e39d4583fa63c0bc0a5df64a4fe672e573045ca7896
+Y = a209a3c3aaf245dee5dd8cc4471f429281977ccb8a185a51ec7fb9abcebf52aa
+
+Curve = P-256
+# N = -22
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63253b
+X = c0dd241a50d48f99fcc7a186a6d44e0763ec90478e1def8e36f5c4e950d67afb
+Y = 7d798cd0569ab748be583239153f9d2725871a841fc15d29f3432e9427351393
+
+Curve = P-256
+# N = -21
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63253c
+X = 3250fcf686637c7b2e4ac86eb473bca53a582139f42b1523fd76364e67399e83
+Y = bd183cbc9982ca6d684cf6f2e281477376832c3dc4a9957dea21db5f8e2b73f6
+
+Curve = P-256
+# N = -20
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63253d
+X = 83a01a9378395bab9bcd6a0ad03cc56d56e6b19250465a94a234dc4c6b28da9a
+Y = 891b64911d08cdcc5195a14629ed48a360ddfd4596dc0ab007dbf5557909bf47
+
+Curve = P-256
+# N = -19
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63253e
+X = cb6d2861102c0c25ce39b7c17108c507782c452257884895c1fc7b74ab03ed83
+Y = a7289eb3db2610afa3ca18eff292931b5b698e92cf05c1fc1c6eaf8ad4313255
+
+Curve = P-256
+# N = -18
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63253f
+X = 1057e0ab5780f470defc9378d1c7c87437bb4c6f9ea55c63d936266dbd781fda
+Y = 090e9ba4ea341a246056482026911a58233ee4a4a10b0e08727c4cc6c395ba5d
+
+Curve = P-256
+# N = -17
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632540
+X = 47776904c0f1cc3a9c0984b66f75301a5fa68678f0d64af8ba1abce34738a73e
+Y = 55ffa1184a46a8d89dce7a9a889b717c7e4d7fbcd72a8cc0cd0878008e0e0323
+
+Curve = P-256
+# N = -16
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632541
+X = 76a94d138a6b41858b821c629836315fcd28392eff6ca038a5eb4787e1277c6e
+Y = 567a019dcbe0d9f2934f5e4a1ee178df7a665ffcf0387455f162228db473aeef
+
+Curve = P-256
+# N = -15
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632542
+X = f0454dc6971abae7adfb378999888265ae03af92de3a0ef163668c63e59b9d5f
+Y = 4a46c11ba6d1d2e1b19a6b1ae069bc19d5c4de328a4a05c0b81a6321f2fcb0c9
+
+Curve = P-256
+# N = -14
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632543
+X = 54e77a001c3862b97a76647f4336df3cf126acbe7a069c5e5709277324d2920b
+Y = 0a660e43d60bce8bbdede073fa5d183c8e8e15898caf6ff7e45837d09f2f4c8a
+
+Curve = P-256
+# N = -13
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632544
+X = 177c837ae0ac495a61805df2d85ee2fc792e284b65ead58a98e15d9d46072c01
+Y = 9c44a731b1415aa85dbf6e524bf0b18dd911eb3d5e04b20c63bc441d10384027
+
+Curve = P-256
+# N = -12
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632545
+X = 741dd5bda817d95e4626537320e5d55179983028b2f82c99d500c5ee8624e3c4
+Y = f88f4b9463c7a024a98c7caab7784eab71146ed4ca45a358e66a00dd32bb7e2c
+
+Curve = P-256
+# N = -11
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632546
+X = 3ed113b7883b4c590638379db0c21cda16742ed0255048bf433391d374bc21d1
+Y = 6f66df64333b375edb37bc505b0b3975f6f2fb26a16776251d07110317d5c8bf
+
+Curve = P-256
+# N = -10
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632547
+X = cef66d6b2a3a993e591214d1ea223fb545ca6c471c48306e4c36069404c5723f
+Y = 78799d5cd655517091edc32262c4b3efa6f212d7018ae11135cb4455bb50f88c
+
+Curve = P-256
+# N = -9
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632548
+X = ea68d7b6fedf0b71878938d51d71f8729e0acb8c2c6df8b3d79e8a4b90949ee0
+Y = d5d8bb358d36031978feb569b5715f37b28eb0165b217dc017a5ddb5b22fb705
+
+Curve = P-256
+# N = -8
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632549
+X = 62d9779dbee9b0534042742d3ab54cadc1d238980fce97dbb4dd9dc1db6fb393
+Y = 52a533416e1627dcb00ea288ee98311f5d12ae0a4418958725abf595f0f66a81
+
+Curve = P-256
+# N = -7
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254a
+X = 8e533b6fa0bf7b4625bb30667c01fb607ef9f8b8a80fef5b300628703187b2a3
+Y = 8c14e2411fcce7ca92f9607c590a6fffac38c9cd34fbe4de3aa1e5793e0bff4b
+
+Curve = P-256
+# N = -6
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254b
+X = b01a172a76a4602c92d3242cb897dde3024c740debb215b4c6b0aae93c2291a9
+Y = 17a3ef8acdc8252b9013f1d20458fc86e3ff0890e381e9420283b7ac7038801d
+
+Curve = P-256
+# N = -5
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254c
+X = 51590b7a515140d2d784c85608668fdfef8c82fd1f5be52421554a0dc3d033ed
+Y = 1f3e82566fb58d83751e40c9407586d9f2fed1002b27f7772e2f44bb025e925b
+
+Curve = P-256
+# N = -4
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254d
+X = e2534a3532d08fbba02dde659ee62bd0031fe2db785596ef509302446b030852
+Y = 1f0ea8a4b39cc339e62011a02579d289b103693d0cf11ffaa3bd3dc0e7b12739
+
+Curve = P-256
+# N = -3
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254e
+X = 5ecbe4d1a6330a44c8f7ef951d4bf165e6c6b721efada985fb41661bc6e7fd6c
+Y = 78cb9bf2b6670082c8b4f931e59b5d1327d54fcac7b047c265864ed85d82afcd
+
+Curve = P-256
+# N = -2
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254f
+X = 7cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978
+Y = f888aaee24712fc0d6c26539608bcf244582521ac3167dd661fb4862dd878c2e
+
+Curve = P-256
+# N = -1
+N = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550
+X = 6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296
+Y = b01cbd1c01e58065711814b583f061e9d431cca994cea1313449bf97c840ae0a
+
+Curve = P-256
+# N = 0
+N = 0000000000000000000000000000000000000000000000000000000000000000
+X = 0000000000000000000000000000000000000000000000000000000000000000
+Y = 0000000000000000000000000000000000000000000000000000000000000000
+
+Curve = P-256
+# N = 1
+N = 0000000000000000000000000000000000000000000000000000000000000001
+X = 6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296
+Y = 4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5
+
+Curve = P-256
+# N = 2
+N = 0000000000000000000000000000000000000000000000000000000000000002
+X = 7cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978
+Y = 07775510db8ed040293d9ac69f7430dbba7dade63ce982299e04b79d227873d1
+
+Curve = P-256
+# N = 3
+N = 0000000000000000000000000000000000000000000000000000000000000003
+X = 5ecbe4d1a6330a44c8f7ef951d4bf165e6c6b721efada985fb41661bc6e7fd6c
+Y = 8734640c4998ff7e374b06ce1a64a2ecd82ab036384fb83d9a79b127a27d5032
+
+Curve = P-256
+# N = 4
+N = 0000000000000000000000000000000000000000000000000000000000000004
+X = e2534a3532d08fbba02dde659ee62bd0031fe2db785596ef509302446b030852
+Y = e0f1575a4c633cc719dfee5fda862d764efc96c3f30ee0055c42c23f184ed8c6
+
+Curve = P-256
+# N = 5
+N = 0000000000000000000000000000000000000000000000000000000000000005
+X = 51590b7a515140d2d784c85608668fdfef8c82fd1f5be52421554a0dc3d033ed
+Y = e0c17da8904a727d8ae1bf36bf8a79260d012f00d4d80888d1d0bb44fda16da4
+
+Curve = P-256
+# N = 6
+N = 0000000000000000000000000000000000000000000000000000000000000006
+X = b01a172a76a4602c92d3242cb897dde3024c740debb215b4c6b0aae93c2291a9
+Y = e85c10743237dad56fec0e2dfba703791c00f7701c7e16bdfd7c48538fc77fe2
+
+Curve = P-256
+# N = 7
+N = 0000000000000000000000000000000000000000000000000000000000000007
+X = 8e533b6fa0bf7b4625bb30667c01fb607ef9f8b8a80fef5b300628703187b2a3
+Y = 73eb1dbde03318366d069f83a6f5900053c73633cb041b21c55e1a86c1f400b4
+
+Curve = P-256
+# N = 8
+N = 0000000000000000000000000000000000000000000000000000000000000008
+X = 62d9779dbee9b0534042742d3ab54cadc1d238980fce97dbb4dd9dc1db6fb393
+Y = ad5accbd91e9d8244ff15d771167cee0a2ed51f6bbe76a78da540a6a0f09957e
+
+Curve = P-256
+# N = 9
+N = 0000000000000000000000000000000000000000000000000000000000000009
+X = ea68d7b6fedf0b71878938d51d71f8729e0acb8c2c6df8b3d79e8a4b90949ee0
+Y = 2a2744c972c9fce787014a964a8ea0c84d714feaa4de823fe85a224a4dd048fa
+
+Curve = P-256
+# N = 10
+N = 000000000000000000000000000000000000000000000000000000000000000a
+X = cef66d6b2a3a993e591214d1ea223fb545ca6c471c48306e4c36069404c5723f
+Y = 878662a229aaae906e123cdd9d3b4c10590ded29fe751eeeca34bbaa44af0773
+
+Curve = P-256
+# N = 11
+N = 000000000000000000000000000000000000000000000000000000000000000b
+X = 3ed113b7883b4c590638379db0c21cda16742ed0255048bf433391d374bc21d1
+Y = 9099209accc4c8a224c843afa4f4c68a090d04da5e9889dae2f8eefce82a3740
+
+Curve = P-256
+# N = 12
+N = 000000000000000000000000000000000000000000000000000000000000000c
+X = 741dd5bda817d95e4626537320e5d55179983028b2f82c99d500c5ee8624e3c4
+Y = 0770b46a9c385fdc567383554887b1548eeb912c35ba5ca71995ff22cd4481d3
+
+Curve = P-256
+# N = 13
+N = 000000000000000000000000000000000000000000000000000000000000000d
+X = 177c837ae0ac495a61805df2d85ee2fc792e284b65ead58a98e15d9d46072c01
+Y = 63bb58cd4ebea558a24091adb40f4e7226ee14c3a1fb4df39c43bbe2efc7bfd8
+
+Curve = P-256
+# N = 14
+N = 000000000000000000000000000000000000000000000000000000000000000e
+X = 54e77a001c3862b97a76647f4336df3cf126acbe7a069c5e5709277324d2920b
+Y = f599f1bb29f4317542121f8c05a2e7c37171ea77735090081ba7c82f60d0b375
+
+Curve = P-256
+# N = 15
+N = 000000000000000000000000000000000000000000000000000000000000000f
+X = f0454dc6971abae7adfb378999888265ae03af92de3a0ef163668c63e59b9d5f
+Y = b5b93ee3592e2d1f4e6594e51f9643e62a3b21ce75b5fa3f47e59cde0d034f36
+
+Curve = P-256
+# N = 16
+N = 0000000000000000000000000000000000000000000000000000000000000010
+X = 76a94d138a6b41858b821c629836315fcd28392eff6ca038a5eb4787e1277c6e
+Y = a985fe61341f260e6cb0a1b5e11e87208599a0040fc78baa0e9ddd724b8c5110
+
+Curve = P-256
+# N = 17
+N = 0000000000000000000000000000000000000000000000000000000000000011
+X = 47776904c0f1cc3a9c0984b66f75301a5fa68678f0d64af8ba1abce34738a73e
+Y = aa005ee6b5b957286231856577648e8381b2804428d5733f32f787ff71f1fcdc
+
+Curve = P-256
+# N = 18
+N = 0000000000000000000000000000000000000000000000000000000000000012
+X = 1057e0ab5780f470defc9378d1c7c87437bb4c6f9ea55c63d936266dbd781fda
+Y = f6f1645a15cbe5dc9fa9b7dfd96ee5a7dcc11b5c5ef4f1f78d83b3393c6a45a2
+
+Curve = P-256
+# N = 19
+N = 0000000000000000000000000000000000000000000000000000000000000013
+X = cb6d2861102c0c25ce39b7c17108c507782c452257884895c1fc7b74ab03ed83
+Y = 58d7614b24d9ef515c35e7100d6d6ce4a496716e30fa3e03e39150752bcecdaa
+
+Curve = P-256
+# N = 20
+N = 0000000000000000000000000000000000000000000000000000000000000014
+X = 83a01a9378395bab9bcd6a0ad03cc56d56e6b19250465a94a234dc4c6b28da9a
+Y = 76e49b6de2f73234ae6a5eb9d612b75c9f2202bb6923f54ff8240aaa86f640b8
+
+Curve = P-256
+# N = 21
+N = 0000000000000000000000000000000000000000000000000000000000000015
+X = 3250fcf686637c7b2e4ac86eb473bca53a582139f42b1523fd76364e67399e83
+Y = 42e7c342667d359397b3090d1d7eb88c897cd3c33b566a8215de24a071d48c09
+
+Curve = P-256
+# N = 22
+N = 0000000000000000000000000000000000000000000000000000000000000016
+X = c0dd241a50d48f99fcc7a186a6d44e0763ec90478e1def8e36f5c4e950d67afb
+Y = 8286732ea96548b841a7cdc6eac062d8da78e57ce03ea2d60cbcd16bd8caec6c
+
+Curve = P-256
+# N = 23
+N = 0000000000000000000000000000000000000000000000000000000000000017
+X = 0e91c7239c2640d7d28a3e39d4583fa63c0bc0a5df64a4fe672e573045ca7896
+Y = 5df65c3b550dba221a22733bb8e0bd6d7e68833575e7a5ae138046543140ad55
+
+Curve = P-256
+# N = 24
+N = 0000000000000000000000000000000000000000000000000000000000000018
+X = db474918ec62ad7eb652b8b0af585aba9b2f394723ab103776e27d7d8c2aa4cb
+Y = 85811d39bb743f28439794607b06d52b8a249c47830a37d221db656c94a7ab55
+
+Curve = P-256
+# N = 25
+N = 0000000000000000000000000000000000000000000000000000000000000019
+X = 3a67e2554b0c0bb685f4f52d8c07fa8441652fc5b76f1b2484a4dc45f200d687
+Y = 27d0f1872f1fcf4326daf267163afb0d8c188af735a7618aa9ed16b302f79324
+
+Curve = P-256
+# N = 26
+N = 000000000000000000000000000000000000000000000000000000000000001a
+X = f5757c012185a599d1f3958b0ae68aa5dffd3d78e1a2eee67417001857658331
+Y = 393a6ed02c7675b24b1238d1d2a08fd50a6e5e5108df840bff533dfe7268dec4
+
+Curve = P-256
+# N = 27
+N = 000000000000000000000000000000000000000000000000000000000000001b
+X = 184ffa5819d80d51deba2fac4611f378576355bd683e54abf2e201173b0883d1
+Y = c0a66e276688f359a4c6d90826cb999545bdeccc63f0491620d242c260906e6f
+
+Curve = P-256
+# N = 28
+N = 000000000000000000000000000000000000000000000000000000000000001c
+X = 38d86fa55b4fd1586c5f05fae7acfc4d36cbdcf7fa62129339246f69c4300e4e
+Y = 3f93b85a4abd0f277ff6a68909e7022ef8b9fcbb91d89bb79f930dc0ff69e47b
+
+Curve = P-256
+# N = 29
+N = 000000000000000000000000000000000000000000000000000000000000001d
+X = d6d33adefa195b07a7c36da090853b8cfd8cd1c688b58a41dedd693d1c784def
+Y = 84aaba16ee195d7e3f78245f558a5dcb09a166ab4b95eded550c124593d1bca6
+
+Curve = P-256
+# N = 30
+N = 000000000000000000000000000000000000000000000000000000000000001e
+X = 409f8da21aea236a5f5a1904d0310c1c6192a67d0da08936319869a8ad0838a3
+Y = 70dcf7b1cf008e570e26e72bd3bd40f73e99a0ec162a6793e163d2c72a1e8f5a
+
+Curve = P-256
+# N = 31
+N = 000000000000000000000000000000000000000000000000000000000000001f
+X = 301d9e502dc7e05da85da026a7ae9aa0fac9db7d52a95b3e3e3f9aa0a1b45b8b
+Y = 6551b6f6b3061223e0d23c026b017d72298d9ae46887ca61d58db6aea17ee267
+
+Curve = P-256
+# N = 32
+N = 0000000000000000000000000000000000000000000000000000000000000020
+X = 2377c7d690a242ca6c45074e8ea5beefaa557fd5b68371d9d1475bd52a7ed0e1
+Y = 47a13fb98413a4393f8d90e9bf901b7e6658a6cdecf46716e7c067b1ddb8d2b2
+
+Curve = P-256
+# N = 33
+N = 0000000000000000000000000000000000000000000000000000000000000021
+X = 9807d699fcd81356fa9aa25b89d9d34ea03b0a533aa872fd65c100f3cb2cd793
+Y = c2a59cdccab11bf286a01a4d1d091b2fffe630b96c5878532f6bf92479634af4
+
+Curve = P-256
+# N = 34
+N = 0000000000000000000000000000000000000000000000000000000000000022
+X = 2f9e6ebf717def118d1a092fce97133919cf2d31b7f8be6cfb7fdbe16820999e
+Y = 7aeeaad8532f8821e3cb1a14d0f524f61682d2950aedea0d756b880306be0b2f
+
+Curve = P-256
+# N = 35
+N = 0000000000000000000000000000000000000000000000000000000000000023
+X = d58d4a589ed27d168ffa3ad7326c48ca94e8e1fe92af9700a12d389033bb291a
+Y = d45514d102726b8576ea92632dc7fef667271c163b034979a5b0c9c6f586b9d5
+
+Curve = P-256
+# N = 36
+N = 0000000000000000000000000000000000000000000000000000000000000024
+X = da5bd2d111c3731d14281d73d5e965a384e94cbf9664dc227d2a45b9abb598ef
+Y = 6166fc1938f06c542246527b075df922bb15925817b426a492333c242044ae5f
+
+Curve = P-256
+# N = 37
+N = 0000000000000000000000000000000000000000000000000000000000000025
+X = 419a6a646ddb817dd6b0978611a826aae0d21379246bfd4473a92894502b3348
+Y = 332544cf1102f584545c9fb1954c2fd513c6d072f3dee1e2db1d6c81b09214b2
+
+Curve = P-256
+# N = 38
+N = 0000000000000000000000000000000000000000000000000000000000000026
+X = 971581bdd1356ea1b317d7b29059611176788153b4d38f8d81155d60576d8c46
+Y = 870ce8afdf0d59c19dd52f1e8654186aaae84346183f325380c784e32bcec592
+
+Curve = P-256
+# N = 39
+N = 0000000000000000000000000000000000000000000000000000000000000027
+X = 22a682f7c3996d4d42014976a179046e547b942dd2d138d4a0c199ddfb2776c4
+Y = 4f4606b0102223eeb918c9835a54356c979dcc310265b0685347f649cbaa285d
+
+Curve = P-256
+# N = 40
+N = 0000000000000000000000000000000000000000000000000000000000000028
+X = bea01e7daad46131bd5b18584d0ee0c457b44d35ae412c0faa74b4da1aac91e6
+Y = 21edd4e6094dac05d882ded2816bdaf610fb9f1a296ddcd934c7ff6431d51d1c
+
+Curve = P-256
+# N = 41
+N = 0000000000000000000000000000000000000000000000000000000000000029
+X = 67a6bec240dee0651cf258d2e6cfe8aa6067c5c3d4175a593a7de694995d2fa2
+Y = de692b7022d131586c249b49464d44991542c7ee209aca6c49c24ce1441feed5
+
+Curve = P-256
+# N = 42
+N = 000000000000000000000000000000000000000000000000000000000000002a
+X = 6780c5fc70275e2c7061a0e7877bb174deadeb9887027f3fa83654158ba7f50c
+Y = 3cba8c34bc35d20e81f730ac1c7bd6d661a942f90c6a9ca55c512f9e4a001266
+
+Curve = P-256
+# N = 43
+N = 000000000000000000000000000000000000000000000000000000000000002b
+X = 986ae2506f1ff104d04230861d8f4b498f4bc4c6d009b30f7544dc129b82d28d
+Y = 003cccc0a6460e0ae328a4d97d3c7b61d86fc6289c189f2525110c441bb07e97
+
+Curve = P-256
+# N = 44
+N = 000000000000000000000000000000000000000000000000000000000000002c
+X = 4756686a0d7e11cb04211f7813b498c2170bff9af47aab0e652d0380ac8d4f9b
+Y = ce334fdb54863a6f2ffc258f3474c4eb65755aa6384890b40e824a9882f785d0
+
+Curve = P-256
+# N = 45
+N = 000000000000000000000000000000000000000000000000000000000000002d
+X = a891d06670bde99b3ecd0f5ddff0672e0f5f609edd29d6d979c78080fae0ba03
+Y = b596cd922cbfa1c1419a88c4033c1ce71c6b38f0feb0f2ccefc3edc8166934ae
+
+Curve = P-256
+# N = 46
+N = 000000000000000000000000000000000000000000000000000000000000002e
+X = b1bb852cfea701fc42caaa1a5b5eb6a5174e94f87c4d3b0612b46293eb5925f8
+Y = 1d337dc66c7874cb46047d206fd1e6cd2075978e09ef174f783ea1f98bde3cb0
+
+Curve = P-256
+# N = 47
+N = 000000000000000000000000000000000000000000000000000000000000002f
+X = 42c315cc48958708595361ea83071bbcdd5b31583e19066d51d689227b1c0d7c
+Y = 649a61ce571b95852914d1dfbb7a799074f1a1e1eb87f164d6c4a72bb2f9b1b9
+
+Curve = P-256
+# N = 48
+N = 0000000000000000000000000000000000000000000000000000000000000030
+X = 9482fb0e492539ec8cce745be070cda11c2e92960a201a61abfb9dc69e4536ca
+Y = 351d9ca745f157f91a5d638ca7534e63f63d5e295707bfbb1fad863bf58cc1c8
+
+Curve = P-256
+# N = 49
+N = 0000000000000000000000000000000000000000000000000000000000000031
+X = f785b0e098068875bb22b146866e6c0528fb7ea9758fd4fd7d228ce6a5674455
+Y = 73fdb0bf6080da6ee15c767f0d9f5b414b04b6fd5f3aa60ae7bc490c10d62408
+
+Curve = P-256
+# N = 50
+N = 0000000000000000000000000000000000000000000000000000000000000032
+X = ba6821cba9bab3ba57a98127482a5de00c108a6ac3241ebb508c58a24d9edba2
+Y = 8841c5de60c4af3b87375ec78cbd21e7e70a85292d77eb4f8f218b036784e120
+
+Curve = P-256
+# N = 51
+N = 0000000000000000000000000000000000000000000000000000000000000033
+X = 672c4a514d9de43eaadee6863c1d68bc95f7eb56e81008ff044360f0018e22b1
+Y = 548c7e9196a25bfe611de5a4ace203f7136246589704d9419935399191f37104
+
+Curve = P-256
+# N = 52
+N = 0000000000000000000000000000000000000000000000000000000000000034
+X = 194e35c4ec2f25ef537105d2b2e54c1803eb2d0a04492e3d2e1d72d04b978b18
+Y = af42679ac14ea798bdb78f1683c4294c68ea7d11e83d569bc049fe2403cf4764
+
+Curve = P-256
+# N = 53
+N = 0000000000000000000000000000000000000000000000000000000000000035
+X = 6f01bd49c9d952455a47802254b88039982b1ca78de9b983f126ec9f7449d036
+Y = 1562080ff1d5deab11a0f21a608776cea78551bfc3749b08360233dd989e17db
+
+Curve = P-256
+# N = 54
+N = 0000000000000000000000000000000000000000000000000000000000000036
+X = 6fc0cd2131b9eb0587c40153ae03fcc8f4b7dbe02cdc59fa4aa8b7d7c3a3dc7d
+Y = d4b77618646b0513c0e9d83bf3764561ac630a8e350bae857b065b1731fde2a4
+
+Curve = P-256
+# N = 55
+N = 0000000000000000000000000000000000000000000000000000000000000037
+X = 079dba7ba068c9267571a109fe7fea2cc2a595b762c1eadadec1dff7df6e60a0
+Y = dc1e19b743d4d1811d223f9d2a9588ab83eb2df35751a397fb0da5aeb4824dea
+
+Curve = P-256
+# N = 56
+N = 0000000000000000000000000000000000000000000000000000000000000038
+X = 6f9a14fbbcf2815a42e8b595d0d5a0eb956463496f67dc0d60a7520a83fb632e
+Y = c8429eb87b404f2a854c2de4c776c9db9d87f2b8dd394a5b92d75da2f24ecf29
+
+Curve = P-256
+# N = 57
+N = 0000000000000000000000000000000000000000000000000000000000000039
+X = c116e30ebb4d2865126d45a8ea907f86289d406e2d6c6bd88abd97b1d0f56077
+Y = e9478823c35b30c2b8b16d9bb13b87657d5bd5e89e59c8c5313fd7fda410c206
+
+Curve = P-256
+# N = 58
+N = 000000000000000000000000000000000000000000000000000000000000003a
+X = ec247d216208539a58912acd04d6df1f8b0b3c9affdc599e9e2481f254419b1d
+Y = ca31ca404b25347546e93b667595a5ddfc715e31da31f5982b9106263ac41fde
+
+Curve = P-256
+# N = 59
+N = 000000000000000000000000000000000000000000000000000000000000003b
+X = 665f1a6ffe0c6437765b2784fca9bdf7e50941119e8dc8eca2b6ea0e0faa4b45
+Y = 490e2ca49ffd18c26e8cca29f7eac37f7dede5bf81e215bc6e25a6602b7f4ccf
+
+Curve = P-256
+# N = 60
+N = 000000000000000000000000000000000000000000000000000000000000003c
+X = 05dae8c2c5a5afba7e53b9efcac1d0b8224559146918d320879bb82d96ef4963
+Y = bb07a44d03c08119e2f782d0d70304cef299e802d1d3bf625690236051d34324
+
+Curve = P-256
+# N = 61
+N = 000000000000000000000000000000000000000000000000000000000000003d
+X = 059ccb19edd3da9a2d3a6b3d8d9900013e7910a08b724fd55939ac380d32af0e
+Y = bb6ad7eccad49159da65281b9345638e1621f7a33956cecd928e1e3c97fe91d1
+
+Curve = P-256
+# N = 62
+N = 000000000000000000000000000000000000000000000000000000000000003e
+X = 571c05c84021edcec4b1ac999829ecd80f8216b239c67f269f88ff57ae8cce2b
+Y = f9325afc175332192dfb3d9f305f499affcc0cf8a6bb2ddbac0128c284ab8115
+
+Curve = P-256
+# N = 63
+N = 000000000000000000000000000000000000000000000000000000000000003f
+X = 6a9501d85bf5dc802a1f28a08acc7d8fdf53c8af01a7cd3832a290825d8bdac1
+Y = ca640ad19347374381c6c6e44a3c56a3f8461b5c697a6f3530aff53d5f1ef1a3
+
+Curve = P-256
+# N = 64
+N = 0000000000000000000000000000000000000000000000000000000000000040
+X = 0a0643fb8fcc14def67a6a5eb1bf8e9125b35edc7338d816aa4110a6b90ee785
+Y = 553438324a9e7955c520dacda2920e700da10d00e7012ed7bac0d100861f9cc2
+
+Curve = P-384
+# N = -64
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52933
+X = c1e179aa178a780046e35841766073612ea5e5abd26608f259a599fc9a8425a3ea639d94cbe63fde1d69c70f9327605f
+Y = 3c7bd091b2435929f6459e8e9afc8e4d523f89bf5dbdf1540817d6e1505de4a8110ce79e3df2214774ba0f4c7a90715a
+
+Curve = P-384
+# N = -63
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52934
+X = b32e89eb942aab112cae508f5164ca6cac334769de358b333c968cfbb83c8f7b941560583def5431afd574f7e008f8af
+Y = 4e1c518e99268efcdb1d40969fc002a4588f03b748c123f986322285fb66ff69ca2511ffa618b5e537e541f7bb1ee1d3
+
+Curve = P-384
+# N = -62
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52935
+X = fad756f52978ca376b086258bfaaac8a3a42d10c5d6cb507c8ca4c2efce2a9692f29d569dcf86b74aacc18a3c5d13f84
+Y = 4854ecff8a943566631934121d70f1731bcb8ad0a8252d22476f6b5234263363d2b9795b85a991d341160c06a5f07a38
+
+Curve = P-384
+# N = -61
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52936
+X = 0a12151e620a81a2870b7900c1c476895f729644b4fa011fa92542dbf5872edcb5e5a6d1fb4071db5c24cc10bda2cc75
+Y = 7a837fd69f1514481eaffdb8a43f57f3bb862b38a44e260e309a6cbae565f9667b046797980473b75ec1ea823a5c17c3
+
+Curve = P-384
+# N = -60
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52937
+X = 22f2d6f4248636552c2f806ca08d835bf6c15cd3df2f83cff6ea265604a50599458e0d6d3f0d7daf3a81734e1a5b276a
+Y = 910e7499f3d19f7e17795004df2b676ff5c5a78378f7b9b224be2290a949370b8d94c16873b89b4dd3d06a0c837e418f
+
+Curve = P-384
+# N = -59
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52938
+X = cc42cb6ad9f7161a4296f482176d1b0191e7691569202b98a2b93e41e5a75d8abbf7b15b29f59772ba77d70f99fe20b0
+Y = 44294494527ae92c6e9b919af960597a15bddc0bb61c76a13dce973204ab2145e7d6e98a9cc787e2258b2acca1db29c0
+
+Curve = P-384
+# N = -58
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52939
+X = 2dba210e4d863e5dd6b431f835c444c8fa54c48cf585a1ee081f91a2141db69c5ee6baa05a4f63e8ecedcd4f9e4d8bcd
+Y = c61e2b24da041cfb4ebda9c5c6714b9022230ce6d948d6e1dde5350528839065e76d7485acf41db61ed4d72097c54f59
+
+Curve = P-384
+# N = -57
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc5293a
+X = 8654ddc7eb10d5a84f1cec9879cabece6c3eb8b272461fc778baa6599653227907fd3823a2b10416709d6a38b6ecb8bd
+Y = ced8f993eef6d1777cfa985089c1362f8bda6619b702815b82e2ec2e55e381be77292429544664ae479841581ca87ab6
+
+Curve = P-384
+# N = -56
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc5293b
+X = 2d56e829a6fb82c64a4697d960af951e9067ae91f926d34306da48a8aaeb7869b6a67e6d27426e0442aa03b36e1988df
+Y = 09c9aeb11e30f80a45b4c00d5f99ba5182ce2a79952ce55c2db914f4ce881165348a9939e9318b7f7599706f0f3b8035
+
+Curve = P-384
+# N = -55
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc5293c
+X = a059cd75571b3507307d064e7750ab08f36d925a4f0112f5f22f519eeae1eb0130d0a0e2e2ee7c873bb25771ff2b4f85
+Y = bf09519d3a58a08ffd92731403203cd103ceecaeaa9bf700f05feb82787dca54577f389377b6432a5137855b96372933
+
+Curve = P-384
+# N = -54
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc5293d
+X = bb0ff1b32114d1740890f276e61f8041c55c05c89ed8af7c8776542902a392ad231a5a3dda24dffe6b2de3474fadeb4e
+Y = b901067fedd0040c7a7bb4f04d26d41ea59972fa56a814a00d6483d2cfef638e0d3c59fe7879bf6c2efbe2f0bcb08fcd
+
+Curve = P-384
+# N = -53
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc5293e
+X = a0e5cd10144167c592288353932cf40888e935bdd5f169ba8f41cbe07c3e20b6ff2ca2a90bdc08ac90903c9d776e9fa3
+Y = edf21868e72eab0155abd0a3e1831b4129c6936bc5e9fdb118240f51e80802f4f362341462be685503a3aaa62161a781
+
+Curve = P-384
+# N = -52
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc5293f
+X = e217fd47cff91786a8eb87b0cf545dca6a0eca0fa0bbdc7aaad84294bd6fa726a3131880b817b7828611cae7d96a1985
+Y = 3d7cac441254d845583048417d1e352491edc33ee84baf721a7dd7ea8bf2d7b8fc0bb988295f932a20b4b1279d4dafc8
+
+Curve = P-384
+# N = -51
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52940
+X = 8bc6057da46fdafba86d2c9e23c2f5bc0b4a2a1247e8f2cc7126ed3b510b0341a618a8cc08d1b992ffe06fbae0068fb0
+Y = 015e60d80977e59f040d5dd02e0e67a2888018a6a66b51f2bd012dfd663168f9ab392f7a229f880a934a68481dd3d316
+
+Curve = P-384
+# N = -50
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52941
+X = ae98b89e108d372ac57c52eed44931f735cc34c5b98037cff20c1c93b6706101dd56a283b13f9a29cf0106d9107660d7
+Y = 9d1683e51907e1dbd6faf8f01e91c1f8ee06a1725e6ab30079b01b8a421fcc17cf797d7c65631d615bc6ee7176fd83b6
+
+Curve = P-384
+# N = -49
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52942
+X = a6c36459d1243ff7f504f32fc1211afd7486cc53003ed182dd74d976a49117348828f5b191d03d1c9da43e8e5a0e8cf2
+Y = a7d8603206938e26e3142efa3d758e2ff428daac05cc9a4bdd7660a87de52da3c75e43f33a847609d192248a739c4bf5
+
+Curve = P-384
+# N = -48
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52943
+X = eb967d99bfe2cdfec7d895a5b4edde398642eb77303050301fcabe3798c46ace66629c442ca537cc68701396222c0089
+Y = 16c1a2d91b21bbd5c0dc58e8829be6255aa5f03624f0075953e4d5d4ce5bee0fbf26bc3989866def86d295d1734a70b9
+
+Curve = P-384
+# N = -47
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52944
+X = 1273f595eaba5df1a06f4ca5fa30e0bcc870bf64c76762c0e2a9530742a384f121e9e8ccc22e6b2cd5254db0689a30fe
+Y = 9d8c803701f7e7345f24aad3597d4b605e501cd51f357c3dec331dbdea7eb79258eb85fbd120374f3425066ac2a70b31
+
+Curve = P-384
+# N = -46
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52945
+X = ebdbf7a1fbd628764fbb7a168061b8c7c6e3211321841d9ae8e9bece5debbbd3a33fac59a8097c72fa4c28f0bb83b8f8
+Y = cfe62132004c17e30f47f7c1df7f8c3a5492cbc2d80f4c402ffaee9f590f43e240db9b44620c62190fa011cd61426fba
+
+Curve = P-384
+# N = -45
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52946
+X = 6ce3bf11431d1d9c3bce43bec4f4609eadd9c644fd8393e3258449c2e28cd17cb03d491de84ea016a5b68a56bbfef50f
+Y = 3ccda1d8b4dc9fb18389f8aac6abd5426e77ff1c84b1b557a728b01d4378881e7efa25ccbde1a301c922166f83a8fb8e
+
+Curve = P-384
+# N = -44
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52947
+X = 3a67a337e9f9801a467c5ab6d69a1f94757634a28a2d794c0abe75b32c89fc4182cfcdb920e29ee6228d345d53f529c0
+Y = 37898b4b7dddd62bda553e265a26fac28c7ac1eba5deced32c0ce45c03619f1e97115781da4e285e28ec0536475fcf1c
+
+Curve = P-384
+# N = -43
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52948
+X = 9c3adb9111fe252ca5a2ff485cf5a64f4de52ef9689a5eb5aba8ddfa4745a605aa49a4148fbebc6780dddc249a26a33d
+Y = 7c1726a07ec50b24af4607f4dd4b7d65962347bad0fa899cb3963b3fef7595cc2451a47d8a508bdfcbbfff24b8caaf9e
+
+Curve = P-384
+# N = -42
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52949
+X = e035e8b33efae0987f6b994529285be4a9d55093d2b9c155c086e2b3c025a8c1c860097bb529b268b7ff95719518ac0a
+Y = 6813bd89af29ff11934cb32ad35f6c64984eab605bd14d4a943ed686e985f6fe8aaef1ff43c6a5b491fb413d5c13b516
+
+Curve = P-384
+# N = -41
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc5294a
+X = 2ce37b2917ad0d5c411a5ed920a88b095185d456b279a18410d10234b609b8c7077b05ca6a94f76d10f3f39e87c76293
+Y = 40d81c1f845f14462542190b7b523fb0454a4847707fcab87df709247a6dd843b225b74a05a2e202307582851d589f81
+
+Curve = P-384
+# N = -40
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc5294b
+X = 37cf990dee523641d57328fb34cdf4dbd3795a0b7df5072f1c67e1a4991b2d388809a316e9abf06d301d2ae1c1283ec1
+Y = 90e175521359a8c1f8cfa7ba6156909141487770fb18cc8591bbefb36f8188bf55cd4cf7aad898a4e98909e0812764ef
+
+Curve = P-384
+# N = -39
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc5294c
+X = 9bc6b654362621678224c2dcc11702de31c65d0bd2d3642c35b72c15f264347c4983e9bc8a47b24d15ac797ea8f8fedb
+Y = bb7d0f6c7b679b138eb8112f6e104c97245e7de7e7a88f38dd1a76cfbc5db73f952866502a7a27773f686cfc5443032b
+
+Curve = P-384
+# N = -38
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc5294d
+X = 081dd3666a57be69b8d22bf15ec27b014b32060b20f018c3f0467a5eb8c359725c7bb4e179bb42b5acf9732879a8bc72
+Y = 9f80d2b90a0c1732b4c8a0f7efa69d775b9e406dfd1830652b29e905a98a994b656da22b3761da3503baec634f505fc1
+
+Curve = P-384
+# N = -37
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc5294e
+X = 1221b1e1be96dfe8fdb4300af2deaadcd850ac1e45c8fcb941c36c0122a10654e56ba2d9cafcb4482a07272d05de389d
+Y = af4dda0575a127c7e527b9f1d1de99e7fa66ac22769a26824dccedbe772e8143a0b0d56cce4098dcacc004df6c622d8c
+
+Curve = P-384
+# N = -36
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc5294f
+X = bc7f0d480a8627fcdcbdf8371a720e49499d70a40ba07ccda1159432b4aa3c9ff05c7a3bcce6bb083bf618c1f6729597
+Y = 4160dbbfbf7e58db7284ca4ab192f733d5f0fd6c5cb4ee4b03254fc66a04b4c0712c0771bf0ef33964cd85e70d98a284
+
+Curve = P-384
+# N = -35
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52950
+X = 77c12dceca498ff99b9863d46535a5abc3675bf4f728f3ac55a0270e5859145dc998b7fd7b3813ca29e4ae10ae1410ea
+Y = 111cae43cbd892c52cfd0f2f42efd961c691804769b0bcfbffb785b7311d4dd23df3a0f3410dd98cca8b81f863411088
+
+Curve = P-384
+# N = -34
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52951
+X = 1aee48c2f0f4678b942a66ccd2385edbd1831e58722e5d974aa2569489b3a75599741028cd1141c4266e9778df65df0f
+Y = 28f7476e2976bac460f2ba40e239b8ec74e0cb6dc4ed61c0b8994c4a78bbbf10ab8982d842466b3a02f077b05ef09afd
+
+Curve = P-384
+# N = -33
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52952
+X = 38dbd58238c21bbca92758f2773bb6c955492715879f54bdaf246b3f70bec90d631eaed97add3fe2aefd7fec482c802a
+Y = 7d73d996b207e776ed5881eb7c8c2cf0100ab58e9aee0a0e84790d5456426ad72ceba1575440bc8fa665f999d92ccc44
+
+Curve = P-384
+# N = -32
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52953
+X = 7f7356c5e0fbc6678bab99df1fd9b2b49f81618d6d99af63612ccf2cc4acaf5c44819b88e217ecd3cce82fe55ff86ed6
+Y = 1ffc4ce21dfaf5b5bc2e5a0464b3599dd43aa1a21f3c190d1594bf66a69738ad38a2eaeb559eb43dac11d318969e7884
+
+Curve = P-384
+# N = -31
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52954
+X = f2e6f06f0ea533e804fcfa12c087d446c73e3336394c98c59d3993124d374e62061fa485bd1b8a650c8361dba9eb28b9
+Y = 70791b9b3dff43b9061bbd9ed030042eb5fbe579ae87f2cec04f4653eebdae31c177fd382d036140cead0a4687ad97f3
+
+Curve = P-384
+# N = -30
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52955
+X = d43bef39667b4579be8d64327f27b3e7a5e64b4d7661e143ba3b0775f23dd1321ffb816b13a131da163d59596752a5bf
+Y = f92d78d6ff41148d6e9a4b62f9601a2578a0eeabf5bfbb769f9ccee1b84eaf1134e089b68cbf1b85f490fa51d00bcaac
+
+Curve = P-384
+# N = -29
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52956
+X = f1bc35f9656c6eead7b75810ce554ee56e0af4f41cbcde50fa46d04f4d4dfca2ad69e407f57b1e27977bb83b1eb1a373
+Y = dba7b685aa64323308cc3ab83f0d4c2372851388926b038face08f69f5cf17c6c00170adb87b75f1ac1f2fa20d7050d6
+
+Curve = P-384
+# N = -28
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52957
+X = 1f1eebd69cfac8d8d63fd685f9fe8d6bd99ba6fb33270854c8bade1c652b661b64f1d4fefa439e57c7e6a187c296ce28
+Y = c02bdccd50fa56c5db396a43873b710003c53eb89ee1534e93fd3b71efa10f2c26c041a74cd5d508b92835a334cf81eb
+
+Curve = P-384
+# N = -27
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52958
+X = 9c5fa2c13f418e623c316d5a82c8b70508e3acaa2b4a8d3a4acb49c0d7ba04e220761bc15898e1b06b4eedfa23e2e546
+Y = 09be21f34f8a7ae5a5017eafc348409e6b020e482561a6aa90fea9ae426de71bf10d3b4cdec0ae64ad604a9c860b78ad
+
+Curve = P-384
+# N = -26
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52959
+X = 88dae96dc76ab8cb2b88d363d1fceec6a4373c71c90399a7cebbb25a07792c4314fcdf3bc85652769c2cd48bb6526e80
+Y = 428937bdbbf05cb444ac12edfef35e9f329a3bb9658f5663958beceb349ee7315e7bcdc0f33b556f86f9e7ae745a6865
+
+Curve = P-384
+# N = -25
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc5295a
+X = e4c6d5cb9183a6709ee9eb526794676207c4d76fab5ce0a3555746bd28fda97431a8a58b3dcb2ca446f41be83716be9a
+Y = 5c8dbaadc55a87ba3ffd80e9a228b356a6bd1e72ea6dd0df9d7f47501a295a5cf656a84353b68dd30050ab2919553768
+
+Curve = P-384
+# N = -24
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc5295b
+X = 0b2b78bdb399c17bb3c12c1dff5b51a9f826f0160455eccb7f4ba75043f7ce6b133f171d399bb367b8fc503a52c7119d
+Y = c4a419bfa1e78f2e9ca0ea7ab18a86b216b0e5d6be6572ac42ee8111bb92f50d3f5609cd790994ae7b3142bcb93b97cf
+
+Curve = P-384
+# N = -23
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc5295c
+X = 3cb647a5df014c23e741a4a8000d5eb822c0102fd4293a78a68749c30c7f9aa484a900a91f7c4ab51e555ebc684aac81
+Y = d7cffb865707722fb69907a1423e734b9efc384fde7437c885040faa81529c96f641de08beb4641d8649a016f2a5d4eb
+
+Curve = P-384
+# N = -22
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc5295d
+X = 1a3abc4dfb1d29d848746b20fe44656bc320904bf33c4192c00e43cbf53606dee42d354877204a5831f375ccf9ada337
+Y = 1cb6a3ded2b6c6ef8e3f5dfa47a6f662073bc2e5247f500d43ebc3e866286bbcd2ff8f93ff77d8a257468af04c292fa6
+
+Curve = P-384
+# N = -21
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc5295e
+X = 27935df4e25c6f47c7817121057d46e1606290985f8283f5f9936136bf42cdb746a37313df88fd64626b4c175eb77422
+Y = c7f5e5c4b7672b32654e5c8672e1cadb5b0d2b513f863948a7a263b1939ea4abd4907266c710f3ec62a9f915ef39607b
+
+Curve = P-384
+# N = -20
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc5295f
+X = 605508ec02c534bceee9484c86086d2139849e2b11c1a9ca1e2808dec2eaf161ac8a105d70d4f85c50599be5800a623f
+Y = aea7117869d53947e0ff5efc47abc5f8c7e489c65c59a0ecac510ee48ccef92116d16647721c984b71dc73c825271122
+
+Curve = P-384
+# N = -19
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52960
+X = 8d481dab912bc8ab16858a211d750b77e07dbecca86cd9b012390b430467aabf59c8651060801c0e9599e68713f5d41b
+Y = 5ea6d00fedeb9f7a841660d59f996faf4dd6e4975efc655fa6b4cd028523f172ee0045a8f7ffb19b966a4f828a1addba
+
+Curve = P-384
+# N = -18
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52961
+X = dfb1fe3a40f7ac9b64c41d39360a7423828b97cb088a4903315e402a7089fa0f8b6c2355169cc9c99dfb44692a9b93dd
+Y = bac535edbc4a1394bdc5975daa781e9ec59cb3e3bd2d118193a80bb65e36e2366e9748fb913f580c85c99e7bdcc13add
+
+Curve = P-384
+# N = -17
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52962
+X = 4099952208b4889600a5ebbcb13e1a32692befb0733b41e6dcc614e42e5805f817012a991af1f486caf3a9add9ffcc03
+Y = a1306b8887ccfa67c6b8ba6b509fca67e9c52c07ff752f32648682d880dc774bfb25b2cf55697f13059af10b1dc4f65f
+
+Curve = P-384
+# N = -16
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52963
+X = d5d89c3b5282369c5fbd88e2b231511a6b80dff0e5152cf6a464fa9428a8583bac8ebc773d157811a462b892401dafcf
+Y = 27eadd621ed6f92dbe7e92a1656bb70e2be2b03bf1d5c42463545a81bbf585442edef3460b640ddc97dd48ab1454c98c
+
+Curve = P-384
+# N = -15
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52964
+X = b3d13fc8b32b01058cc15c11d813525522a94156fff01c205b21f9f7da7c4e9ca849557a10b6383b4b88701a9606860b
+Y = ead6e618206e9d59e4fb64dac9e9b4e411453b5ee28b650b7b2eeebc8c2040257c72db064d7b50af67a2a773cc08429d
+
+Curve = P-384
+# N = -14
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52965
+X = e8c8f94d44fbc2396bbeac481b89d2b0877b1dffd23e7dc95de541eb651cca2c41aba24dbc02de6637209accf0f59ea0
+Y = 76e51bbca903751f6cd4340921ad3756cc479e6e188d728637ce6bec5f62f0b603b9745eaaf621dd2811a362e4984777
+
+Curve = P-384
+# N = -13
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52966
+X = a567ba97b67aea5bafdaf5002ffcc6ab9632bff9f01f873f6267bcd1f0f11c139ee5f441abd99f1baaf1ca1e3b5cbce7
+Y = 21e4c74c6760cce79bb1beb850e9b133ae7aa6afb96cd13f79cd641fa87a82988894347c8dde75829bdc5ed9c90bd633
+
+Curve = P-384
+# N = -12
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52967
+X = 952a7a349bd49289ab3ac421dcf683d08c2ed5e41f6d0e21648af2691a481406da4a5e22da817cb466da2ea77d2a7022
+Y = 5fcdf0507b4a43fa9cfad215190990d1f6047fc931e75f1446fd74f69e694af1fce559b9768bc1dd610945341de42e91
+
+Curve = P-384
+# N = -11
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52968
+X = 099056e27da7b998da1eeec2904816c57fe935ed5837c37456c9fd14892d3f8c4749b66e3afb81d626356f3b55b4ddd8
+Y = d1b3f3dcb1cf5469977afaabb53a1fc6903b1127203c9c02bc006c0be4ad5cd9ab992aec9c5500ca82a2457fc73a1f44
+
+Curve = P-384
+# N = -10
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52969
+X = a669c5563bd67eec678d29d6ef4fde864f372d90b79b9e88931d5c29291238cced8e85ab507bf91aa9cb2d13186658fb
+Y = 567748d5183ed860dd26f7c24a0f132208fee6aaf3e7c3ce3afd20873c48fa56d6927e69db7d77266887b09648c5de22
+
+Curve = P-384
+# N = -9
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc5296a
+X = 8f0a39a4049bcb3ef1bf29b8b025b78f2216f7291e6fd3bac6cb1ee285fb6e21c388528bfee2b9535c55e4461079118b
+Y = 9d3881ebc749fe29bad3b5acdd3c56866564c2835c3bff39489877ab51264cfc618bc100202ae497d9d25b075399b507
+
+Curve = P-384
+# N = -8
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc5296b
+X = 1692778ea596e0be75114297a6fa383445bf227fbe58190a900c3c73256f11fb5a3258d6f403d5ece6e9b269d822c87d
+Y = 232dc9a8ff2bef957cac7745c24702f1ddaab52392ade32b42e3cf3d13f113e594521e15322e8f729095405cfdd4f52d
+
+Curve = P-384
+# N = -7
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc5296c
+X = 283c1d7365ce4788f29f8ebf234edffead6fe997fbea5ffa2d58cc9dfa7b1c508b05526f55b9ebb2040f05b48fb6d0e1
+Y = 6b8a366f9e1be47745ad102473e96fb8e59e2798128668d62636d32fe242dda8cf27b120cd5870619b99b3263aed1073
+
+Curve = P-384
+# N = -6
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc5296d
+X = 627be1acd064d2b2226fe0d26f2d15d3c33ebcbb7f0f5da51cbd41f26257383021317d7202ff30e50937f0854e35c5df
+Y = f68995b34c074e3de41922593eb0ea8a4d36acad9bb088b36679b09ec8eabbe8fb3ba4717b1e9acee8cc5bf82c0f06cb
+
+Curve = P-384
+# N = -5
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc5296e
+X = 11de24a2c251c777573cac5ea025e467f208e51dbff98fc54f6661cbe56583b037882f4a1ca297e60abcdbc3836d84bc
+Y = 705969388bbf06d2f0a7c816f5ff183ad7b4bb88ab2a211773679acc496fe513ce889791f51704cce7bbeb55193e8ec5
+
+Curve = P-384
+# N = -4
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc5296f
+X = 138251cd52ac9298c1c8aad977321deb97e709bd0b4ca0aca55dc8ad51dcfc9d1589a1597e3a5120e1efd631c63e1835
+Y = 35351d679659d1e9ce175d7e7e54a99e923ba26e7543f60c54f19c3086d55b22128c7840c8445a96ab60e3fe4d8f1298
+
+Curve = P-384
+# N = -3
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52970
+X = 077a41d4606ffa1464793c7e5fdc7d98cb9d3910202dcd06bea4f240d3566da6b408bbae5026580d02d7e5c70500c831
+Y = 366a0835f4f3bd7c82f44169fd5603667adf4be37aeea55a0897b3f123eee1523db542931b4a2d6749a0d7a0f5d0e20e
+
+Curve = P-384
+# N = -2
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52971
+X = 08d999057ba3d2d969260045c55b97f089025959a6f434d651d207d19fb96e9e4fe0e86ebe0e64f85b96a9c75295df61
+Y = 717f0e05a4e4c312484017200292458b4d8a278a43933bc16fb1afa0da954bd9a002bc15b2c61dd29eafe190f56bf17f
+
+Curve = P-384
+# N = -1
+N = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52972
+X = aa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7
+Y = c9e821b569d9d390a26167406d6d23d6070be242d765eb831625ceec4a0f473ef59f4e30e2817e6285bce2846f15f1a0
+
+Curve = P-384
+# N = 0
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+X = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Y = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+
+Curve = P-384
+# N = 1
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
+X = aa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7
+Y = 3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f
+
+Curve = P-384
+# N = 2
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002
+X = 08d999057ba3d2d969260045c55b97f089025959a6f434d651d207d19fb96e9e4fe0e86ebe0e64f85b96a9c75295df61
+Y = 8e80f1fa5b1b3cedb7bfe8dffd6dba74b275d875bc6cc43e904e505f256ab4255ffd43e94d39e22d61501e700a940e80
+
+Curve = P-384
+# N = 3
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003
+X = 077a41d4606ffa1464793c7e5fdc7d98cb9d3910202dcd06bea4f240d3566da6b408bbae5026580d02d7e5c70500c831
+Y = c995f7ca0b0c42837d0bbe9602a9fc998520b41c85115aa5f7684c0edc111eacc24abd6be4b5d298b65f28600a2f1df1
+
+Curve = P-384
+# N = 4
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004
+X = 138251cd52ac9298c1c8aad977321deb97e709bd0b4ca0aca55dc8ad51dcfc9d1589a1597e3a5120e1efd631c63e1835
+Y = cacae29869a62e1631e8a28181ab56616dc45d918abc09f3ab0e63cf792aa4dced7387be37bba569549f1c02b270ed67
+
+Curve = P-384
+# N = 5
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005
+X = 11de24a2c251c777573cac5ea025e467f208e51dbff98fc54f6661cbe56583b037882f4a1ca297e60abcdbc3836d84bc
+Y = 8fa696c77440f92d0f5837e90a00e7c5284b447754d5dee88c986533b6901aeb3177686d0ae8fb33184414abe6c1713a
+
+Curve = P-384
+# N = 6
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006
+X = 627be1acd064d2b2226fe0d26f2d15d3c33ebcbb7f0f5da51cbd41f26257383021317d7202ff30e50937f0854e35c5df
+Y = 09766a4cb3f8b1c21be6dda6c14f1575b2c95352644f774c99864f613715441604c45b8d84e165311733a408d3f0f934
+
+Curve = P-384
+# N = 7
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007
+X = 283c1d7365ce4788f29f8ebf234edffead6fe997fbea5ffa2d58cc9dfa7b1c508b05526f55b9ebb2040f05b48fb6d0e1
+Y = 9475c99061e41b88ba52efdb8c1690471a61d867ed799729d9c92cd01dbd225630d84ede32a78f9e64664cdac512ef8c
+
+Curve = P-384
+# N = 8
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008
+X = 1692778ea596e0be75114297a6fa383445bf227fbe58190a900c3c73256f11fb5a3258d6f403d5ece6e9b269d822c87d
+Y = dcd2365700d4106a835388ba3db8fd0e22554adc6d521cd4bd1c30c2ec0eec196bade1e9cdd1708d6f6abfa4022b0ad2
+
+Curve = P-384
+# N = 9
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009
+X = 8f0a39a4049bcb3ef1bf29b8b025b78f2216f7291e6fd3bac6cb1ee285fb6e21c388528bfee2b9535c55e4461079118b
+Y = 62c77e1438b601d6452c4a5322c3a9799a9b3d7ca3c400c6b7678854aed9b3029e743efedfd51b68262da4f9ac664af8
+
+Curve = P-384
+# N = 10
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a
+X = a669c5563bd67eec678d29d6ef4fde864f372d90b79b9e88931d5c29291238cced8e85ab507bf91aa9cb2d13186658fb
+Y = a988b72ae7c1279f22d9083db5f0ecddf70119550c183c31c502df78c3b705a8296d8195248288d997784f6ab73a21dd
+
+Curve = P-384
+# N = 11
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b
+X = 099056e27da7b998da1eeec2904816c57fe935ed5837c37456c9fd14892d3f8c4749b66e3afb81d626356f3b55b4ddd8
+Y = 2e4c0c234e30ab96688505544ac5e0396fc4eed8dfc363fd43ff93f41b52a3255466d51263aaff357d5dba8138c5e0bb
+
+Curve = P-384
+# N = 12
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c
+X = 952a7a349bd49289ab3ac421dcf683d08c2ed5e41f6d0e21648af2691a481406da4a5e22da817cb466da2ea77d2a7022
+Y = a0320faf84b5bc0563052deae6f66f2e09fb8036ce18a0ebb9028b096196b50d031aa64589743e229ef6bacce21bd16e
+
+Curve = P-384
+# N = 13
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d
+X = a567ba97b67aea5bafdaf5002ffcc6ab9632bff9f01f873f6267bcd1f0f11c139ee5f441abd99f1baaf1ca1e3b5cbce7
+Y = de1b38b3989f3318644e4147af164ecc5185595046932ec086329be057857d66776bcb8272218a7d6423a12736f429cc
+
+Curve = P-384
+# N = 14
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e
+X = e8c8f94d44fbc2396bbeac481b89d2b0877b1dffd23e7dc95de541eb651cca2c41aba24dbc02de6637209accf0f59ea0
+Y = 891ae44356fc8ae0932bcbf6de52c8a933b86191e7728d79c8319413a09d0f48fc468ba05509de22d7ee5c9e1b67b888
+
+Curve = P-384
+# N = 15
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f
+X = b3d13fc8b32b01058cc15c11d813525522a94156fff01c205b21f9f7da7c4e9ca849557a10b6383b4b88701a9606860b
+Y = 152919e7df9162a61b049b2536164b1beebac4a11d749af484d1114373dfbfd9838d24f8b284af50985d588d33f7bd62
+
+Curve = P-384
+# N = 16
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010
+X = d5d89c3b5282369c5fbd88e2b231511a6b80dff0e5152cf6a464fa9428a8583bac8ebc773d157811a462b892401dafcf
+Y = d815229de12906d241816d5e9a9448f1d41d4fc40e2a3bdb9caba57e440a7abad1210cb8f49bf2236822b755ebab3673
+
+Curve = P-384
+# N = 17
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011
+X = 4099952208b4889600a5ebbcb13e1a32692befb0733b41e6dcc614e42e5805f817012a991af1f486caf3a9add9ffcc03
+Y = 5ecf94777833059839474594af603598163ad3f8008ad0cd9b797d277f2388b304da4d2faa9680ecfa650ef5e23b09a0
+
+Curve = P-384
+# N = 18
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012
+X = dfb1fe3a40f7ac9b64c41d39360a7423828b97cb088a4903315e402a7089fa0f8b6c2355169cc9c99dfb44692a9b93dd
+Y = 453aca1243b5ec6b423a68a25587e1613a634c1c42d2ee7e6c57f449a1c91dc89168b7036ec0a7f37a366185233ec522
+
+Curve = P-384
+# N = 19
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013
+X = 8d481dab912bc8ab16858a211d750b77e07dbecca86cd9b012390b430467aabf59c8651060801c0e9599e68713f5d41b
+Y = a1592ff0121460857be99f2a60669050b2291b68a1039aa0594b32fd7adc0e8c11ffba5608004e646995b07e75e52245
+
+Curve = P-384
+# N = 20
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014
+X = 605508ec02c534bceee9484c86086d2139849e2b11c1a9ca1e2808dec2eaf161ac8a105d70d4f85c50599be5800a623f
+Y = 5158ee87962ac6b81f00a103b8543a07381b7639a3a65f1353aef11b733106dde92e99b78de367b48e238c38dad8eedd
+
+Curve = P-384
+# N = 21
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015
+X = 27935df4e25c6f47c7817121057d46e1606290985f8283f5f9936136bf42cdb746a37313df88fd64626b4c175eb77422
+Y = 380a1a3b4898d4cd9ab1a3798d1e3524a4f2d4aec079c6b7585d9c4e6c615b532b6f8d9838ef0c139d5606eb10c69f84
+
+Curve = P-384
+# N = 22
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016
+X = 1a3abc4dfb1d29d848746b20fe44656bc320904bf33c4192c00e43cbf53606dee42d354877204a5831f375ccf9ada337
+Y = e3495c212d49391071c0a205b859099df8c43d1adb80aff2bc143c1799d794422d00706b0088275da8b97510b3d6d059
+
+Curve = P-384
+# N = 23
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017
+X = 3cb647a5df014c23e741a4a8000d5eb822c0102fd4293a78a68749c30c7f9aa484a900a91f7c4ab51e555ebc684aac81
+Y = 28300479a8f88dd04966f85ebdc18cb46103c7b0218bc8377afbf0557ead636809be21f6414b9be279b65fea0d5a2b14
+
+Curve = P-384
+# N = 24
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018
+X = 0b2b78bdb399c17bb3c12c1dff5b51a9f826f0160455eccb7f4ba75043f7ce6b133f171d399bb367b8fc503a52c7119d
+Y = 3b5be6405e1870d1635f15854e75794de94f1a29419a8d53bd117eee446d0af1c0a9f63186f66b5184cebd4446c46830
+
+Curve = P-384
+# N = 25
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000019
+X = e4c6d5cb9183a6709ee9eb526794676207c4d76fab5ce0a3555746bd28fda97431a8a58b3dcb2ca446f41be83716be9a
+Y = a37245523aa57845c0027f165dd74ca95942e18d15922f206280b8afe5d6a5a209a957bbac49722cffaf54d7e6aac897
+
+Curve = P-384
+# N = 26
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a
+X = 88dae96dc76ab8cb2b88d363d1fceec6a4373c71c90399a7cebbb25a07792c4314fcdf3bc85652769c2cd48bb6526e80
+Y = bd76c842440fa34bbb53ed12010ca160cd65c4469a70a99c6a741314cb6118cda184323e0cc4aa90790618528ba5979a
+
+Curve = P-384
+# N = 27
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001b
+X = 9c5fa2c13f418e623c316d5a82c8b70508e3acaa2b4a8d3a4acb49c0d7ba04e220761bc15898e1b06b4eedfa23e2e546
+Y = f641de0cb075851a5afe81503cb7bf6194fdf1b7da9e59556f015651bd9218e30ef2c4b2213f519b529fb56479f48752
+
+Curve = P-384
+# N = 28
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c
+X = 1f1eebd69cfac8d8d63fd685f9fe8d6bd99ba6fb33270854c8bade1c652b661b64f1d4fefa439e57c7e6a187c296ce28
+Y = 3fd42332af05a93a24c695bc78c48efffc3ac147611eacb16c02c48e105ef0d2d93fbe57b32a2af746d7ca5dcb307e14
+
+Curve = P-384
+# N = 29
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001d
+X = f1bc35f9656c6eead7b75810ce554ee56e0af4f41cbcde50fa46d04f4d4dfca2ad69e407f57b1e27977bb83b1eb1a373
+Y = 2458497a559bcdccf733c547c0f2b3dc8d7aec776d94fc70531f70960a30e8383ffe8f5147848a0e53e0d05ef28faf29
+
+Curve = P-384
+# N = 30
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e
+X = d43bef39667b4579be8d64327f27b3e7a5e64b4d7661e143ba3b0775f23dd1321ffb816b13a131da163d59596752a5bf
+Y = 06d2872900beeb729165b49d069fe5da875f11540a4044896063311e47b150edcb1f76487340e47a0b6f05af2ff43553
+
+Curve = P-384
+# N = 31
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001f
+X = f2e6f06f0ea533e804fcfa12c087d446c73e3336394c98c59d3993124d374e62061fa485bd1b8a650c8361dba9eb28b9
+Y = 8f86e464c200bc46f9e442612fcffbd14a041a8651780d313fb0b9ac114251cd3e8802c6d2fc9ebf3152f5ba7852680c
+
+Curve = P-384
+# N = 32
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020
+X = 7f7356c5e0fbc6678bab99df1fd9b2b49f81618d6d99af63612ccf2cc4acaf5c44819b88e217ecd3cce82fe55ff86ed6
+Y = e003b31de2050a4a43d1a5fb9b4ca6622bc55e5de0c3e6f2ea6b40995968c751c75d1513aa614bc253ee2ce86961877b
+
+Curve = P-384
+# N = 33
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000021
+X = 38dbd58238c21bbca92758f2773bb6c955492715879f54bdaf246b3f70bec90d631eaed97add3fe2aefd7fec482c802a
+Y = 828c26694df8188912a77e148373d30feff54a716511f5f17b86f2aba9bd9527d3145ea7abbf4370599a066726d333bb
+
+Curve = P-384
+# N = 34
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022
+X = 1aee48c2f0f4678b942a66ccd2385edbd1831e58722e5d974aa2569489b3a75599741028cd1141c4266e9778df65df0f
+Y = d708b891d689453b9f0d45bf1dc647138b1f34923b129e3f4766b3b5874440ee54767d26bdb994c5fd0f8850a10f6502
+
+Curve = P-384
+# N = 35
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023
+X = 77c12dceca498ff99b9863d46535a5abc3675bf4f728f3ac55a0270e5859145dc998b7fd7b3813ca29e4ae10ae1410ea
+Y = eee351bc34276d3ad302f0d0bd10269e396e7fb8964f430400487a48cee2b22cc20c5f0bbef2267335747e089cbeef77
+
+Curve = P-384
+# N = 36
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024
+X = bc7f0d480a8627fcdcbdf8371a720e49499d70a40ba07ccda1159432b4aa3c9ff05c7a3bcce6bb083bf618c1f6729597
+Y = be9f24404081a7248d7b35b54e6d08cc2a0f0293a34b11b4fcdab03995fb4b3e8ed3f88d40f10cc69b327a19f2675d7b
+
+Curve = P-384
+# N = 37
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025
+X = 1221b1e1be96dfe8fdb4300af2deaadcd850ac1e45c8fcb941c36c0122a10654e56ba2d9cafcb4482a07272d05de389d
+Y = 50b225fa8a5ed8381ad8460e2e216618059953dd8965d97db233124188d17ebb5f4f2a9231bf6723533ffb21939dd273
+
+Curve = P-384
+# N = 38
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026
+X = 081dd3666a57be69b8d22bf15ec27b014b32060b20f018c3f0467a5eb8c359725c7bb4e179bb42b5acf9732879a8bc72
+Y = 607f2d46f5f3e8cd4b375f0810596288a461bf9202e7cf9ad4d616fa567566b39a925dd3c89e25cafc45139db0afa03e
+
+Curve = P-384
+# N = 39
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000027
+X = 9bc6b654362621678224c2dcc11702de31c65d0bd2d3642c35b72c15f264347c4983e9bc8a47b24d15ac797ea8f8fedb
+Y = 4482f093849864ec7147eed091efb368dba18218185770c722e5893043a248bf6ad799aed585d888c0979304abbcfcd4
+
+Curve = P-384
+# N = 40
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028
+X = 37cf990dee523641d57328fb34cdf4dbd3795a0b7df5072f1c67e1a4991b2d388809a316e9abf06d301d2ae1c1283ec1
+Y = 6f1e8aadeca6573e073058459ea96f6ebeb7888f04e7337a6e44104c907e773faa32b3075527675b1676f6207ed89b10
+
+Curve = P-384
+# N = 41
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029
+X = 2ce37b2917ad0d5c411a5ed920a88b095185d456b279a18410d10234b609b8c7077b05ca6a94f76d10f3f39e87c76293
+Y = bf27e3e07ba0ebb9dabde6f484adc04fbab5b7b88f8035478208f6db859227bb4dda48b4fa5d1dfdcf8a7d7be2a7607e
+
+Curve = P-384
+# N = 42
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a
+X = e035e8b33efae0987f6b994529285be4a9d55093d2b9c155c086e2b3c025a8c1c860097bb529b268b7ff95719518ac0a
+Y = 97ec427650d600ee6cb34cd52ca0939b67b1549fa42eb2b56bc12979167a090075510dffbc395a4b6e04bec3a3ec4ae9
+
+Curve = P-384
+# N = 43
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002b
+X = 9c3adb9111fe252ca5a2ff485cf5a64f4de52ef9689a5eb5aba8ddfa4745a605aa49a4148fbebc6780dddc249a26a33d
+Y = 83e8d95f813af4db50b9f80b22b4829a69dcb8452f0576634c69c4c0108a6a32dbae5b8175af7420344000dc47355061
+
+Curve = P-384
+# N = 44
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002c
+X = 3a67a337e9f9801a467c5ab6d69a1f94757634a28a2d794c0abe75b32c89fc4182cfcdb920e29ee6228d345d53f529c0
+Y = c87674b4822229d425aac1d9a5d9053d73853e145a21312cd3f31ba3fc9e60e068eea87d25b1d7a1d713facab8a030e3
+
+Curve = P-384
+# N = 45
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002d
+X = 6ce3bf11431d1d9c3bce43bec4f4609eadd9c644fd8393e3258449c2e28cd17cb03d491de84ea016a5b68a56bbfef50f
+Y = c3325e274b23604e7c76075539542abd918800e37b4e4aa858d74fe2bc8777e08105da32421e5cfe36dde9917c570471
+
+Curve = P-384
+# N = 46
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e
+X = ebdbf7a1fbd628764fbb7a168061b8c7c6e3211321841d9ae8e9bece5debbbd3a33fac59a8097c72fa4c28f0bb83b8f8
+Y = 3019decdffb3e81cf0b8083e208073c5ab6d343d27f0b3bfd0051160a6f0bc1cbf2464ba9df39de6f05fee339ebd9045
+
+Curve = P-384
+# N = 47
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002f
+X = 1273f595eaba5df1a06f4ca5fa30e0bcc870bf64c76762c0e2a9530742a384f121e9e8ccc22e6b2cd5254db0689a30fe
+Y = 62737fc8fe0818cba0db552ca682b49fa1afe32ae0ca83c213cce2421581486ca7147a032edfc8b0cbdaf9963d58f4ce
+
+Curve = P-384
+# N = 48
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030
+X = eb967d99bfe2cdfec7d895a5b4edde398642eb77303050301fcabe3798c46ace66629c442ca537cc68701396222c0089
+Y = e93e5d26e4de442a3f23a7177d6419daa55a0fc9db0ff8a6ac1b2a2b31a411ef40d943c576799210792d6a2f8cb58f46
+
+Curve = P-384
+# N = 49
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031
+X = a6c36459d1243ff7f504f32fc1211afd7486cc53003ed182dd74d976a49117348828f5b191d03d1c9da43e8e5a0e8cf2
+Y = 58279fcdf96c71d91cebd105c28a71d00bd72553fa3365b422899f57821ad25b38a1bc0bc57b89f62e6ddb768c63b40a
+
+Curve = P-384
+# N = 50
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000032
+X = ae98b89e108d372ac57c52eed44931f735cc34c5b98037cff20c1c93b6706101dd56a283b13f9a29cf0106d9107660d7
+Y = 62e97c1ae6f81e242905070fe16e3e0711f95e8da1954cff864fe475bde033e7308682829a9ce29ea439118f89027c49
+
+Curve = P-384
+# N = 51
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000033
+X = 8bc6057da46fdafba86d2c9e23c2f5bc0b4a2a1247e8f2cc7126ed3b510b0341a618a8cc08d1b992ffe06fbae0068fb0
+Y = fea19f27f6881a60fbf2a22fd1f1985d777fe7595994ae0d42fed20299ce970554c6d084dd6077f56cb597b8e22c2ce9
+
+Curve = P-384
+# N = 52
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034
+X = e217fd47cff91786a8eb87b0cf545dca6a0eca0fa0bbdc7aaad84294bd6fa726a3131880b817b7828611cae7d96a1985
+Y = c28353bbedab27baa7cfb7be82e1cadb6e123cc117b4508de5822815740d284603f44676d6a06cd5df4b4ed962b25037
+
+Curve = P-384
+# N = 53
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000035
+X = a0e5cd10144167c592288353932cf40888e935bdd5f169ba8f41cbe07c3e20b6ff2ca2a90bdc08ac90903c9d776e9fa3
+Y = 120de79718d154feaa542f5c1e7ce4bed6396c943a16024ee7dbf0ae17f7fd0a0c9dcbea9d4197aafc5c555ade9e587e
+
+Curve = P-384
+# N = 54
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036
+X = bb0ff1b32114d1740890f276e61f8041c55c05c89ed8af7c8776542902a392ad231a5a3dda24dffe6b2de3474fadeb4e
+Y = 46fef980122ffbf385844b0fb2d92be15a668d05a957eb5ff29b7c2d30109c70f2c3a60087864093d1041d10434f7032
+
+Curve = P-384
+# N = 55
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000037
+X = a059cd75571b3507307d064e7750ab08f36d925a4f0112f5f22f519eeae1eb0130d0a0e2e2ee7c873bb25771ff2b4f85
+Y = 40f6ae62c5a75f70026d8cebfcdfc32efc311351556408ff0fa0147d878235aaa880c76b8849bcd5aec87aa569c8d6cc
+
+Curve = P-384
+# N = 56
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000038
+X = 2d56e829a6fb82c64a4697d960af951e9067ae91f926d34306da48a8aaeb7869b6a67e6d27426e0442aa03b36e1988df
+Y = f636514ee1cf07f5ba4b3ff2a06645ae7d31d5866ad31aa3d246eb0b3177ee99cb7566c516ce74808a668f91f0c47fca
+
+Curve = P-384
+# N = 57
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000039
+X = 8654ddc7eb10d5a84f1cec9879cabece6c3eb8b272461fc778baa6599653227907fd3823a2b10416709d6a38b6ecb8bd
+Y = 3127066c11092e88830567af763ec9d0742599e648fd7ea47d1d13d1aa1c7e4088d6dbd5abb99b51b867bea8e3578549
+
+Curve = P-384
+# N = 58
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a
+X = 2dba210e4d863e5dd6b431f835c444c8fa54c48cf585a1ee081f91a2141db69c5ee6baa05a4f63e8ecedcd4f9e4d8bcd
+Y = 39e1d4db25fbe304b142563a398eb46fdddcf31926b7291e221acafad77c6f9918928b79530be249e12b28e0683ab0a6
+
+Curve = P-384
+# N = 59
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003b
+X = cc42cb6ad9f7161a4296f482176d1b0191e7691569202b98a2b93e41e5a75d8abbf7b15b29f59772ba77d70f99fe20b0
+Y = bbd6bb6bad8516d391646e65069fa685ea4223f449e3895ec23168cdfb54deb9182916746338781dda74d5345e24d63f
+
+Curve = P-384
+# N = 60
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003c
+X = 22f2d6f4248636552c2f806ca08d835bf6c15cd3df2f83cff6ea265604a50599458e0d6d3f0d7daf3a81734e1a5b276a
+Y = 6ef18b660c2e6081e886affb20d498900a3a587c8708464ddb41dd6f56b6c8f3726b3e968c4764b22c2f95f47c81be70
+
+Curve = P-384
+# N = 61
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003d
+X = 0a12151e620a81a2870b7900c1c476895f729644b4fa011fa92542dbf5872edcb5e5a6d1fb4071db5c24cc10bda2cc75
+Y = 857c802960eaebb7e15002475bc0a80c4479d4c75bb1d9f1cf6593451a9a069884fb986767fb8c48a13e157ec5a3e83c
+
+Curve = P-384
+# N = 62
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e
+X = fad756f52978ca376b086258bfaaac8a3a42d10c5d6cb507c8ca4c2efce2a9692f29d569dcf86b74aacc18a3c5d13f84
+Y = b7ab1300756bca999ce6cbede28f0e8ce434752f57dad2ddb89094adcbd9cc9b2d4686a37a566e2cbee9f3fa5a0f85c7
+
+Curve = P-384
+# N = 63
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003f
+X = b32e89eb942aab112cae508f5164ca6cac334769de358b333c968cfbb83c8f7b941560583def5431afd574f7e008f8af
+Y = b1e3ae7166d9710324e2bf69603ffd5ba770fc48b73edc0679cddd7a0499009535daedff59e74a1ac81abe0944e11e2c
+
+Curve = P-384
+# N = 64
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040
+X = c1e179aa178a780046e35841766073612ea5e5abd26608f259a599fc9a8425a3ea639d94cbe63fde1d69c70f9327605f
+Y = c3842f6e4dbca6d609ba6171650371b2adc07640a2420eabf7e8291eafa21b56eef31860c20ddeb88b45f0b4856f8ea5
+
+Curve = P-521
+# N = -64
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863c9
+X = 01ab9aa17dce1112ecd14f3d7c0392fec2a67ebdbba81860bbacb614b9ccf8872d271bebd3c5efda3773a7c02c1603e7001df5aab8029a04fd41b53dc38ce320f742
+Y = 018b728f147b716dfa8c55efde83a846a792644e3374d04e23e2f39c45c96178547453e9a45eaf72b4ef0b58461c506a7fbc3e3e5a245f9ac22ba50e8fa75a0720a4
+
+Curve = P-521
+# N = -63
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863ca
+X = 01c132753b64640c457fe82f799acb0a6e8e1ca21b5affa0ddc1e7f54fe4d51b08453ae99661308e125ec63996847586265e75af7d025770ac8d0f5beb6fce8888e5
+Y = 00acb81e7be685fac7e8927e53764dfa2869e561f6cd79bebff9a6a173cac55ddc7ffa2c242313e76943ec08707d0ff8ed7c509a84a4099b5d53162ea52d5fc245ea
+
+Curve = P-521
+# N = -62
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863cb
+X = 01f605dada534c5c8ae020f6ed49f27734e2378b0b7bc177aeaf943ae59581dd5885a38bf246fec516fd213f3fe32bfd4e19f0a8c971ef2a16969627fe31114dc85e
+Y = 00b006927d9674872cfa5ddad385b41c75c80d4f50296ca0b555af197a332e9b5ddf9d7b57ce094d691534ea9491898e1485225d281f8d5a875ce60effdddb55a84a
+
+Curve = P-521
+# N = -61
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863cc
+X = 0115544c4a011407425c92ca7c732a1c7d8f8b6cd17d5b660d1a4cd724b1be8b17177193c11a77dc0b39a5e7fce59a7b32d7952bad1671543c41cb53d8cfcfc376a1
+Y = 00eac206393f539b7a4cf86692d5c66378d38650b7a010bdd34013f685c512a7395ffc0872ab480aac5757cb009fc505fcd4a90dd1163c01a1db47100732b5e89fb4
+
+Curve = P-521
+# N = -60
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863cd
+X = 00038a508e954435eff6ccb82b562ed32ff236f33caef52de9fdf79836e37bbe118392681661adc786c57fb6bf92d04b42fc051c3f6061c252749fd17ffbfca45bdc
+Y = 01724278274e1842b2d524858c6646ce18e964f13071c8455f1666820e5ad6a9f5a5a124e1859fa5402fb4e3320597cd7a4b28b708c8660c1a2b07b9b52c6ef16add
+
+Curve = P-521
+# N = -59
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863ce
+X = 0035aeb454ad31876773063c60342df29eadc7223c5d98901999aae5c2934c222920055693c9b1344c691a90342d64373a8acba8524ec347208863be8a26eb16686b
+Y = 01e7813413eb8181bc4b24f4f35f500e4580ea5b724c99f6fc0b1dd0d10c349102ba473073bb437c2f473602a02229b0013c027d3c7305001ae530b55fc3ac7e05d1
+
+Curve = P-521
+# N = -58
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863cf
+X = 008bc46df1c09851ab92d53b6ad821b5026be61385c801f5277c9871b54c6764d3fdb96a728ad56c650d342a03e174a3106a5479d3ccb04647ad0f583210d81ab70d
+Y = 0026b7006d87b166b95d85b3a72bf404f1f489af8c0e0658ce55ad4ac1b01979ecb01187b41370357e58c4753c5ba35e4899321396e6f406b28e05f74d6d6d3edfa0
+
+Curve = P-521
+# N = -57
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863d0
+X = 00dc53c3e7fcf3c902e04463da75efb25ffa5a8defe72e6dbf85ef3c6d77a521b9f84af300bbde9118b2f66fd5bc64b8a5208372c8fff95c84503475330a4e9a13e2
+Y = 018b1770332b024266d497f8c1193b2b07084ec2f22d3506267649d1814c6f200c15cb7dacf2f2c42795b5c07dfa956d608c56b6ce6f39d5aacdcc528080263bdb70
+
+Curve = P-521
+# N = -56
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863d1
+X = 003cd775038527f32baf7e9056e95b0cbef7638c12398e4b8b019cc29b3435be97f601378e253fef51d25730e56267acca241df04ea2e96c1840b3f739d5ae2df998
+Y = 0187640830bdf6a3a4e88f1e5ca9e03c1edcd4fbcf1eeb0985c683e1a4ab6780b5d74ad58c83455f005d3bce79c3e57340ea1459f04a274b8dc23ef268f90bf7c345
+
+Curve = P-521
+# N = -55
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863d2
+X = 004b52fc4b6d310ce7c4b551e4155c6daca97cb03e9fd9d0a79d6472d4028e8da1a18cca93917cad27e6be17486b1e0b549a7fe9ab4bda96ac4e84ad7ccebd470f5e
+Y = 01ca7a1ab017eb9e51dec7a1586f85e584d19e60bbcee5e95f49ff04eeb582451eaaef557a76a3a5f7b32969f61cba4aca7905fc5dcff95f691585e6932dcf5c910d
+
+Curve = P-521
+# N = -54
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863d3
+X = 01938e65f2a40e6899c6414997e998e0e3e1cb09728861ea138fc6d866fdc6c98505393cf55982451c97dac4214e4dbf052bf707cab63228fdfcf5ae2048a0ce100c
+Y = 009c2aa922f6be3186b163d797596d1762406bcb7ae791df8b17ddd1f1266015b42f39f96057fe824741368d46611f280343f09f82988b6d9a6405b84674472e4bee
+
+Curve = P-521
+# N = -53
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863d4
+X = 0143f6e249195ee693f77b3d0ffd310306dff8688be916895fb727e82f6f948100c44e210e637209a78ed3af581fba4fe12b08153da9c98808166285684cccb69906
+Y = 00fac1703369e714d58b3a9ee5fda8aef6788238c0221bd3de96cabc817fac2ef34eb0209b0afc30c44cf09585621c4b3073fbf5c2043b541195029225222bf3879e
+
+Curve = P-521
+# N = -52
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863d5
+X = 001f32e875ce65d1e6d4c39a55b518749158a4dae03e0c1b4b4a58aef6be769f0693b9259354dcee33a4f00784311b6e5993955114f2afcab7a186177e368b29f6f3
+Y = 01a5c371890487b6e7f476a1574dd11e5903d3406c4451f0b52b5f3ed92ce73c686ee18c5f9e47f6756eeeda88896328810d4294ba06760d6d256cfe66d2b7e4f807
+
+Curve = P-521
+# N = -51
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863d6
+X = 0168395ba51e278415a2025d93b68145f3ccfdf9f5bde34fe9ba3ba316cbf9beea26c2edfe6af07390df1321ae1b1054cbc0fba689ef1d7be2dda8d916fffbcc9504
+Y = 018e33ef0c35fbe5dba9c626ace6bd2c0a86ad227870de3b7f31db1a4e8b521464c36843d49745249ff37b63c9f691c5145af9ff55412c5761e771463ba122a3f784
+
+Curve = P-521
+# N = -50
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863d7
+X = 017176204957627b7a120baf0dbb1aa3f9ca5312b292e34a0cfbd8384cf1be365bc684804ab26d84fe02250a859beaced3f356b6ddab593aebf35386773de84d4766
+Y = 00538ec2a3d004f1eee67c1f815a09774fc22cfcd2c56baf4af3a210e24b7a64afb35073ecde449372a0526c2d1a462f18acc9d671de6c608fb0c0e953952237b070
+
+Curve = P-521
+# N = -49
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863d8
+X = 00a5cb98fa3c0b8c1d57cba40a63bbaba0d39d45c347ae499839f581b8b111dea9eb6bc2a2df52f6284291d8c84e2e345fa87258dab1ac4c04ca0c8cb45049efc0ad
+Y = 01ea236a9abf6f288468ebf64fe408d1eae48b611b987881a4814f8d3c626257407ca22688aabc2a8a3df3ef0d311448d44bb469c0404f4774e2f4640b95d3777b4b
+
+Curve = P-521
+# N = -48
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863d9
+X = 01fb35de3b21557462ac8158e5caec62c8ccae7d6d6672102c334b3cc8a5803e72f42da0980f3f6fbfacdedc21b10ff08ee6641752bd214aea2c87027d612ad879ad
+Y = 0072cb5a53ea7866d21257aa4613b44c0a3e890d8036b2f61d3378ed6b09933d1e4519deb29b5e2681c8483ebd1f04f1c3d7a690db7fb7be35184e6a7e6c2da92b94
+
+Curve = P-521
+# N = -47
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863da
+X = 00afe31f8907048afd5f9cf5083ecc35882ce4e4fe2714033ff897233106c71dd0b2381864a0b9e922ac9cee75a3a9c4dd660a56a130d1ecbb672fda63c9abd59d11
+Y = 01ed06a2379a8d8a01624bd6f3444ab009659fa0f86cb6df6077131580cd890f9b686d89f7f46fb67d5914489f0b8727da18ee35bea660ef98c42cf9a2d0e26f1e29
+
+Curve = P-521
+# N = -46
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863db
+X = 00bbdb162d8284a910021998e2d14f33a8c51a9cfb9a69a8fc5709f753aaf1c4d248a6ddb5626540f81d07c09231d2ec1549f672b6d2bd57d22f64f2ae8093e738a5
+Y = 00c4790f2a6dede9101fe016383543ef4ff547e36042698beb62d131bdb4879093c8d5e7ceeed0abecd282c50bd2373281e848137f4f605a60f1bd3ebd76a69eda65
+
+Curve = P-521
+# N = -45
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863dc
+X = 004969d186aca09e53b879596b8fff2bc0207a58f7f28c147cc07b2df5e3f197286779189b7df8a1f2d9dc8ea1ace5703f0fc2954607b66b70c4a32dec600fc95c1a
+Y = 0017e1364af3272c7b82b2953de0ceb60384ea79d5bdcd8f77becaa7b5e44324bf56472a4d7fd152517a19126178641cd71ecb9c0a26f4c8a9b06b675832fff6fc56
+
+Curve = P-521
+# N = -44
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863dd
+X = 013fdb51df11f0b29b485f0c48a04cca16cfe1cecbe9fd57f6507c3cfcbef88c88cf761e3e73e6509ec7e77fffe912d2b367b25aa02cb1d33a5378f253cdcde738d2
+Y = 002eb373e7b58dd758fcb1b09a4c2fcc709985536f74c6530c63614123fbad483d0d5bb9fe7955dd8e2ca88cc15dc28d7b575edcbdb0665df4adbdcbc4a3450599e5
+
+Curve = P-521
+# N = -43
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863de
+X = 018c0148a165ec58e4fed55022d90544d8a070678aa2ec1419af8ef0f94438fea396fc66ad7aed7d37dda3a74e7a9b3d85ca51f0b62fdee07d20713e3083224f497e
+Y = 00f54455e0f661877965140857c3855c40dbd98816e24e2ebb3285cfc87e60e5f41398029f677864e30e6cd29fd4ab831e856b1246d08949772d76a7d6f9897c5240
+
+Curve = P-521
+# N = -42
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863df
+X = 0161960dcd7bd7263ed37a0a1c0aa146f918874f472a2a5de6f2f5633364979e0bda2868fa8595d78243ea20d4e83c72305e420bebfa3767dcd4b7902612a9491855
+Y = 00953e3022bcc7ea9975a3951f2efce43ede5ff19594a72e113bd259fd0fe33bc48108d72983b1c62179cdb34595d3b331f7beb02295282f8ddcc75af1cad52ade10
+
+Curve = P-521
+# N = -41
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863e0
+X = 0175a140ed79e85e24a763ebfd9d2883082552a523e4b28998a685b85f23864a60c816b931eaf495ccce4c08c3ddc8297bfaddfda1a522cc2af68e00ce952624381e
+Y = 004f696928e7aa1d2b12c90decbc35c6641854a61a7f1611a9cddc217de4dd37deee4c61f1ee130cd825fad591aae05d714208a228a7180c5c13141489f13efd7130
+
+Curve = P-521
+# N = -40
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863e1
+X = 002efdef97e46cd544553a0c67f41886ad969f67883679409022c4ad6090a169b596f85d832dc9767b2bb513eb4d0d01e18f067fffb5ac53dbcfaf456a57824c9d93
+Y = 012771d1c022d7ca6d293b3d5b97819a5957dc0039ef92006908a44cebe2f20ae901b95aca84de23ddbfb0b10861bb55684dd3efe0138a27e1f64a6e0c98c75171a3
+
+Curve = P-521
+# N = -39
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863e2
+X = 0124a0b8f411fbad60755264126356a499029e9661a49b5b907238d9fd62359c6ea7256b0cc58626a1e2ac0bf434e5fa31795b4fa1d48083af670b704119ee33b77c
+Y = 01efd69e91238cca231c9fd565bf9442c663976c84557869eab323f4edbf396f24b7e723a6014697da555c350dbea6bb189d0ded18b49671bf542723239edd749e59
+
+Curve = P-521
+# N = -38
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863e3
+X = 0195aeb1530c7d932a18922563d71ef6e7449078207b610c2c77690815bcef8f312718413823ed8d4ba112ac2ecc9d4e688346f120cb19ae965d853028d72a5f4a8b
+Y = 011f3bd2c33f6cdbdfff3f13f68a77b44fcf79ee2742b649f6f5f93a42082f1eabb7ae0645a69d6e10e11c1c365ffd4867a45d61ae2e6c48fe1f3781e53286842ecf
+
+Curve = P-521
+# N = -37
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863e4
+X = 00944f64a6c21832b67139e798352ded5867c35c5d56c1d59e4229ed0ae6af9d5749bd445763a28856040e58e26ee0980df28c64e76ae4780273f1ac4d59b557a36f
+Y = 00af4811e4fdfd7548bef3b469db0d934e6d01b1900de79a07a6d9ce82594866ecfa234243db8e37c07e47a3a9b66a5fa83cce5b41bfa9677d69ced4067c6b04d5fc
+
+Curve = P-521
+# N = -36
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863e5
+X = 01ad81c98659bd21e082514d5e71894c417b2a25afe471eb8ad9e81a91dac8198aa9f385da9cc679bb96e724672821b585e05323bdc821e585edae56cbf798bd6ef0
+Y = 00de8fd9193071903b189e5125a8fa4c3f073580b8abbedd84689ed7a4392370fe50e50af4f44ebffec58a2469c27967ede22d3b45e8a65674bc5388ed07baa36610
+
+Curve = P-521
+# N = -35
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863e6
+X = 00ddc300757549630a78398b62069e0ba392a267a642b593e0bfc4a780b56f97392bb4806c84fda74023ee4a618608f6b2cea92ff614b5dcc8d8dc1039c9ccd7d718
+Y = 013e42d2f80953803a33e47cbce0f3cf24405aef6c934a27a430b9d869a6e5ce24af654ee8742d38febda3dedadd119618682145b24bdd9bf5b2c14e2c10dbe1f80b
+
+Curve = P-521
+# N = -34
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863e7
+X = 0122f66451d0843fb59448c58962f5b7c130eb8db26b14dbf8bf0e7d84e588581cdea866a98b697d432cc1f1f8993db2173b55ac0435b8317a8ddfeab253d54e4d87
+Y = 00412ec846bddb66cd0c3e0edebe511eac755c8c0a511f5765b72ca8283fb69a4faeaf68d6c1b078595bece7b26417156ebf9455addc248a8e432562457d0265f923
+
+Curve = P-521
+# N = -33
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863e8
+X = 00284195f0978fb969e68c76eb4e3c76f58e52086d482be92613f381421a74236df0abdbea7e2b77ef1ae9a519a57aa53ac2a5ec59186b2ed12d5ea2e1fc649f308d
+Y = 0181bc14f739a9239c948485c43796fa92c5db2aec541f9c399c61fe98969eb53a0d189a91340c2ec740ff428de93e9214c5771002a3dd74a70c9416a5c22c1ee3b2
+
+Curve = P-521
+# N = -32
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863e9
+X = 0166ba3596d20a3a469443707af94ba15b343e3e16654e068038dba7ecefb9e5ebd6ea04a35dc73596ec67d69bd6ba5d1f949cf7475cd6c5c78247915ab876e56a9e
+Y = 01b884f00b2e6bf547eee9ca18a00c1f7d9700842740a00fe6983e20fe39a3d228821dfb3247e732294648b21e3815f0c9203267369a5469e9c96a356566eb5ea955
+
+Curve = P-521
+# N = -31
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863ea
+X = 00d8e9920cf30f0c6615006a58cdb7307b7db574589657c2a6617260a83ca5e7726cd65543a904c9d429fc14c1ac09cd6b220dcfb5e488e248122257d0e0c16a8803
+Y = 00d84fdc4abab599c67820f63ec5deb5cf1374abf9cd70ef37f9f51048d3412e55cf089473cdbb2eb86fec65797351b33d9c55e4268384abce7535b98838c686d2e6
+
+Curve = P-521
+# N = -30
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863eb
+X = 00d087d70d11074b36bb0b6913261570a6b33cf015e1f913a610ea52dbcbae2a3e4435573f35d14754c6352756cc169eac6bf7d9b10f1b0af5956117fab72ec4b081
+Y = 013b2f8073c35023e9c97ee2846a5953d2314321e326b504242c1b8fea99f2d60eacab2a4662e282b5250d861011a279f416f96122b900fe303849b29509a862412c
+
+Curve = P-521
+# N = -29
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863ec
+X = 0174c644d6c94b68287db3c1fbfcb65a085ff9f45131e86265ec28bef38f7664a1305ca9bc06876d72914003ab8e847ffb9ef33d8595d51f6d962c3927618eda25dc
+Y = 00e50c583d0780be6197fa5336a4be48487dfdcc1070349bbe034a30a1486a52cb4841f1de6ad31f26f4af3d8cd28f92cfc0f9866d83d9144042e784443b7de5f3cf
+
+Curve = P-521
+# N = -28
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863ed
+X = 019195646effed8e5f6fec5c29642dd68d1a988bb828d895ed5d116d7f87032133e2949da6c395738534b93220fe2ad07f0b291adc92433ee2dee160709ed9985b0c
+Y = 0088532ac4ff360d60c131d74b8db07cb0b69f92c0cb9a95ad10abbc3a26de951c774cba47d7374f65d4d1b6a30d5232294a7790b212e8bebda53ce37cd458b112c7
+
+Curve = P-521
+# N = -27
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863ee
+X = 0160373edf8218f9b6a762a4d4eb889e646f8739535d0e4f862c33f35187e135854d80b2123da719d48351353aeda0d3163cb215604492ec4568357643017002d68b
+Y = 010ea68faffeb2301e3a1a7d7bfe53f95c05602e6c3a30ad3c44b5a90871e5e4ddfee105b6e126d143abec478b0b5744a8d1b9c0018f62ba534c0c195135a26f48bf
+
+Curve = P-521
+# N = -26
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863ef
+X = 017b61bd55cc8b533222d9857bb0c04dcd1331a02407e9a8576609bc2cbefa11d6aef686bfc27593b717007102d5dd038ed768dd29c10c73e41060d9e9a7e8c685c6
+Y = 003cb25fa15b4621c4415fe693f97d41b9cc374b53860a5d645d34238db8f61e0bd94b22475be6e5b9b728b4a4d53cb82ecca4740093fa700a8d18b5533a464b7bb4
+
+Curve = P-521
+# N = -25
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863f0
+X = 0154e84c6d5c5a9a1834a35874a6f5dff9d20073102651b107b11c772c8c5499994aa91856917c36ee4d56e87e2aa648ff27e41e0eb1c25d3fb13f8c2460bf70ace0
+Y = 0132f02316e8e6efb8c51dd5d707f449f2c0ea56dc14ffdd5f380993d777eae99959211cabca8d043e5f2e1dc8f595a68d0a1121d5ab98d19492bcda431bfb387dcf
+
+Curve = P-521
+# N = -24
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863f1
+X = 00968e98d1008e9d525db447ce5d4930becf0e49a0e6ec40736691391a8862c2cd7f93ad7a9b2d0e4f666fdefaa4a86f6559c710838fa0a4198f44a18c28b69bcef2
+Y = 001e581690d6c08aee831bbb899a75cad5585aaa32d09b5d4fcd4b32d47e77f5569d5b70b6d30c2f8ac97c7a1f605ecb086cfa8a319a2282260275f4ac85f4bb98d6
+
+Curve = P-521
+# N = -23
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863f2
+X = 01ae0b275d7290159376db1cacec5f547b8eee7a39ba785fb282490d234d0cdd45101f6f83fc9af5b0afe9e3f8e9a5ec53e207e1f1ac26ae5806a1c6a5ece2af535c
+Y = 010d36857da1ac7ac7f9975d7a703f97b8e3828a60076f2fa7cd4bce9b87bb3d23f1ef7bcc9e1168030bc3d84d844f822f3ddec4bbaf572dc7a927ea3cac905f2fff
+
+Curve = P-521
+# N = -22
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863f3
+X = 009700ce6190c6d36ca5f1f6e66dc1eae621a7facca319d4b7aabde3122096c4089f74cbfe1018ffcd40adfffcca8b28ca1f904b3a12cae0af934e38650bb6f5a561
+Y = 0004877d81eca96ca94f9e3870529deffefb41b572db1bea063e6a1f02f93a4b97db0bf536325201fd75d0dd13ecd12eb1a3a3bcbd810159def29bce652a5aca5352
+
+Curve = P-521
+# N = -21
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863f4
+X = 01a1cbb2c11a742bd2fb3cc8550859ed3b10268bb98c2ed15e9819523e759c467fa946257eae4d62a309d9497eaed827d75b37ac920393a46d2d42ef399693c8c9ed
+Y = 00e5df6282b07114c2b7d3ed2583a1bf319d17c3ffa63ae6c193e7f5d69094505808208be5ac25b7cd6a414bc5c8d39c113a8364f0e89b63349e19f43bc36345b20a
+
+Curve = P-521
+# N = -20
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863f5
+X = 018bdd7f1b889598a4653deeae39cc6f8cc2bd767c2ab0d93fb12e968fbed342b51709506339cb1049cb11dd48b9bdb3cd5cad792e43b74e16d8e2603bfb11b0344f
+Y = 013a552419c09735a49496f7d696a640f50761180ad4bef46bbbab93aaf6ad2ceedfb25c4222392b1518120513efcf257107c8334dd11163036b22cd78012f66f06b
+
+Curve = P-521
+# N = -19
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863f6
+X = 00998dcce486419c3487c0f948c2d5a1a07245b77e0755df547efff0acdb3790e7f1fa3b3096362669679232557d7a45970dfecf431e725bbde478ff0b2418d6a19b
+Y = 00c82a25f9d95fde12a33c6bdb68aca4dba2982d7511d48430b533af111c9aba88d88c5269c00d1473064f13c666e9ce3c880a5b2761560401bb56f6e596a402fa8a
+
+Curve = P-521
+# N = -18
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863f7
+X = 01bc33425e72a12779eacb2edcc5b63d1281f7e86dbc7bf99a7abd0cfe367de4666d6edbb8525bffe5222f0702c3096dec0884ce572f5a15c423fdf44d01dd99c61d
+Y = 00f2f9166677a49caca21c18b2cc2619c2fdb04f831f2e690daad371b5ff537b3fbbdcb514dfe0856ecc6ea2e4b4badf646258601ea4e607b02eca27be1d27065795
+
+Curve = P-521
+# N = -17
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863f8
+X = 01b00ddb707f130eda13a0b874645923906a99ee9e269fa2b3b4d66524f269250858760a69e674fe0287df4e799b5681380ff8c3042af0d1a41076f817a853110ae0
+Y = 017a97c0e2824e9a89243eee2b1b51222ef94866acb30966ef56729753d4dd5ecdc20625a9b10922f40f2d098a80e9520bdf196faa6b3d48aa0aca4634838f19b9b8
+
+Curve = P-521
+# N = -16
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863f9
+X = 01d17d10d8a89c8ad05dda97da26ac743b0b2a87f66192fd3f3dd632f8d20b188a52943ff18861ca00a0e5965da7985630df0dbf5c8007dcdc533a6c508f81a8402f
+Y = 0185c8cbc3a7d288ffe038eb4e72c2c1968decca1b3c47ff2af13835cf36b4947d3e3e7d1ec6724ab855f4cf8a53626677ad61cffb2d72e79cccad1d8d076438c541
+
+Curve = P-521
+# N = -15
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863fa
+X = 006b6ad89abcb92465f041558fc546d4300fb8fbcc30b40a0852d697b532df128e11b91cce27dbd00ffe7875bd1c8fc0331d9b8d96981e3f92bde9afe337bcb8db55
+Y = 004b9725d8ea8ec6e2958319b2dccc12409c20fb6956452df345b49def9668b7a12a816f9d3766b8f57fdeb71ddcd369366db9026f33bb954226a9cbcb7f5eb8ab9a
+
+Curve = P-521
+# N = -14
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863fb
+X = 01875bc7dc551b1b65a9e1b8ccfaaf84ded1958b401494116a2fd4fb0babe0b3199974fc06c8b897222d79df3e4b7bc744aa6767f6b812efbf5d2c9e682dd3432d74
+Y = 01a35b6dca8a2534a42d299d6f44544b42047b8fedd471ae7d95f7b831647928129d2f887e4e4b0ca7b3ee17640e2ecc23f2a496f0ac57837b41be99607ad8ff2ab5
+
+Curve = P-521
+# N = -13
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863fc
+X = 007e3e98f984c396ad9cd7865d2b4924861a93f736cde1b4c2384eedd2beaf5b866132c45908e03c996a3550a5e79ab88ee94bec3b00ab38eff81887848d32fbcda7
+Y = 00f711a7149287e01256e5e6d9255c12a5f7312af5c792abde3963859851a3e1ded53e42a2a7c74389c0d92022cae340443c9e6615506ee81608d6e5fe04fdd58e36
+
+Curve = P-521
+# N = -12
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863fd
+X = 01c0d9dcec93f8221c5de4fae9749c7fde1e81874157958457b6107cf7a5967713a644e90b7c3fb81b31477fee9a60e938013774c75c530928b17be69571bf842d8c
+Y = 00bfb74a6b95b6d83f01c31e2efc597d35b89c019a548eb6b25ba1bfb54095e83f68292e77bc2790324933ef5906ae4649cf77b458dddb0a519386184e5cd7e4e80f
+
+Curve = P-521
+# N = -11
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863fe
+X = 008a75841259fdedff546f1a39573b4315cfed5dc7ed7c17849543ef2c54f2991652f3dbc5332663da1bd19b1aebe3191085015c024fa4c9a902ecc0e02dda0cdb9a
+Y = 016904cfc03445ded67b62f35788fab04dd6c522a99def42fb6c12d16a2b1f4647d4e43756f174bd5b54c76dcce6eb56acc923537f1c0b7e64a2a778b06d31b737f7
+
+Curve = P-521
+# N = -10
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e913863ff
+X = 0190eb8f22bda61f281dfcfe7bb6721ec4cd901d879ac09ac7c34a9246b11ada8910a2c7c178fcc263299daa4da9842093f37c2e411f1a8e819a87ff09a04f2f3320
+Y = 0014a26947b6e9eb456245154c4f35d4589f3d114debbdae4df4568028759d109d2d40acb62bb2679b44ac909e9c23a814100c9769c68c6055e8d6ab4367eca138a6
+
+Curve = P-521
+# N = -9
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386400
+X = 01585389e359e1e21826a2f5bf157156d488ed34541b988746992c4ab145b8c6b6657429e1396134da35f3c556df725a318f4f50babd85cd28661f45627967cbe207
+Y = 01d5d19e736575120c60f4aaaa85d8516c71cf7759ab11e3144937da45d9c224bb91f2961a8a9fa8537bf00a9130b54027828c93d516d777f0cbc55f15794652d5b1
+
+Curve = P-521
+# N = -8
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386401
+X = 000822c40fb6301f7262a8348396b010e25bd4e29d8a9b003e0a8b8a3b05f826298f5bfea5b8579f49f08b598c1bc8d79e1ab56289b5a6f4040586f9ea54aa78ce68
+Y = 009cce6ee2aabd03b7dfb7025491877ac465bb0712161d3f8ea4af7c219ef988570e76163f55a6ee4b400f45f20f9a3a879660c456bff6b8ecac7529bd0ee0e87fe3
+
+Curve = P-521
+# N = -7
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386402
+X = 0056d5d1d99d5b7f6346eeb65fda0b073a0c5f22e0e8f5483228f018d2c2f7114c5d8c308d0abfc698d8c9a6df30dce3bbc46f953f50fdc2619a01cead882816ecd4
+Y = 01c2d2e48264555d5eef2e27ce85c6297b874a3a7d2fd7db0f228e242675d93421aa942f0d6c321361d46adc5cba6e31e5a061898ed5a2210384a3947436fadadae4
+
+Curve = P-521
+# N = -6
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386403
+X = 01ee4569d6cdb59219532eff34f94480d195623d30977fd71cf3981506ade4ab01525fbcca16153f7394e0727a239531be8c2f66e95657f380ae23731bedf79206b9
+Y = 0021fdaa52f339b0a7951d22d8fab91c4eeed554448c25a57f718dbf56d9dfe575693548d2f1a99b7362069367b21d8b0ddfc238474aa35f2521e1533287a72bb0e8
+
+Curve = P-521
+# N = -5
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386404
+X = 00652bf3c52927a432c73dbc3391c04eb0bf7a596efdb53f0d24cf03dab8f177ace4383c0c6d5e3014237112feaf137e79a329d7e1e6d8931738d5ab5096ec8f3078
+Y = 00a41910e42299fe291375d48ceeb57eed6ee327017178d1ffae1227e8365fcb8f7844976836f8d30c8bceeabfdee30a00862e0ff8da8cab0807e8c33c17214f6f34
+
+Curve = P-521
+# N = -4
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386405
+X = 0035b5df64ae2ac204c354b483487c9070cdc61c891c5ff39afc06c5d55541d3ceac8659e24afe3d0750e8b88e9f078af066a1d5025b08e5a5e2fbc87412871902f3
+Y = 017df6907bd9ed862d498c1fe8714f4b5449aade5109191cd1e4a519c01d0e66f80d860d7c1ab45c7abfaddb08af56a47a114480510fb9662e261de0b803cb91b2f2
+
+Curve = P-521
+# N = -3
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386406
+X = 01a73d352443de29195dd91d6a64b5959479b52a6e5b123d9ab9e5ad7a112d7a8dd1ad3f164a3a4832051da6bd16b59fe21baeb490862c32ea05a5919d2ede37ad7d
+Y = 00c164fc4682059d2226686079393547eb0d0eaa8057d562fce82d0754e05caa3113d1d22b30723a8a4fd2a5312e213c38f30efa36436c5a6fbda0a7735e11793f1a
+
+Curve = P-521
+# N = -2
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386407
+X = 00433c219024277e7e682fcb288148c282747403279b1ccc06352c6e5505d769be97b3b204da6ef55507aa104a3a35c5af41cf2fa364d60fd967f43e3933ba6d783d
+Y = 010b44733807924d98ff580c1311112c0f4a394aef83b25688bf54de5d66f93bd2444c1c882160dae0946c6c805665cdb70b1503416a123f0b08e41ca9299e0be4fd
+
+Curve = P-521
+# N = -1
+N = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386408
+X = 00c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66
+Y = 00e7c6d6958765c43ffba375a04bd382e426670abbb6a864bb97e85042e8d8c199d368118d66a10bd9bf3aaf46fec052f89ecac38f795d8d3dbf77416b89602e99af
+
+Curve = P-521
+# N = 0
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+X = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Y = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+
+Curve = P-521
+# N = 1
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
+X = 00c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66
+Y = 011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650
+
+Curve = P-521
+# N = 2
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002
+X = 00433c219024277e7e682fcb288148c282747403279b1ccc06352c6e5505d769be97b3b204da6ef55507aa104a3a35c5af41cf2fa364d60fd967f43e3933ba6d783d
+Y = 00f4bb8cc7f86db26700a7f3eceeeed3f0b5c6b5107c4da97740ab21a29906c42dbbb3e377de9f251f6b93937fa99a3248f4eafcbe95edc0f4f71be356d661f41b02
+
+Curve = P-521
+# N = 3
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003
+X = 01a73d352443de29195dd91d6a64b5959479b52a6e5b123d9ab9e5ad7a112d7a8dd1ad3f164a3a4832051da6bd16b59fe21baeb490862c32ea05a5919d2ede37ad7d
+Y = 013e9b03b97dfa62ddd9979f86c6cab814f2f1557fa82a9d0317d2f8ab1fa355ceec2e2dd4cf8dc575b02d5aced1dec3c70cf105c9bc93a590425f588ca1ee86c0e5
+
+Curve = P-521
+# N = 4
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004
+X = 0035b5df64ae2ac204c354b483487c9070cdc61c891c5ff39afc06c5d55541d3ceac8659e24afe3d0750e8b88e9f078af066a1d5025b08e5a5e2fbc87412871902f3
+Y = 0082096f84261279d2b673e0178eb0b4abb65521aef6e6e32e1b5ae63fe2f19907f279f283e54ba385405224f750a95b85eebb7faef04699d1d9e21f47fc346e4d0d
+
+Curve = P-521
+# N = 5
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005
+X = 00652bf3c52927a432c73dbc3391c04eb0bf7a596efdb53f0d24cf03dab8f177ace4383c0c6d5e3014237112feaf137e79a329d7e1e6d8931738d5ab5096ec8f3078
+Y = 015be6ef1bdd6601d6ec8a2b73114a8112911cd8fe8e872e0051edd817c9a0347087bb6897c9072cf374311540211cf5ff79d1f007257354f7f8173cc3e8deb090cb
+
+Curve = P-521
+# N = 6
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006
+X = 01ee4569d6cdb59219532eff34f94480d195623d30977fd71cf3981506ade4ab01525fbcca16153f7394e0727a239531be8c2f66e95657f380ae23731bedf79206b9
+Y = 01de0255ad0cc64f586ae2dd270546e3b1112aabbb73da5a808e7240a926201a8a96cab72d0e56648c9df96c984de274f2203dc7b8b55ca0dade1eaccd7858d44f17
+
+Curve = P-521
+# N = 7
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007
+X = 0056d5d1d99d5b7f6346eeb65fda0b073a0c5f22e0e8f5483228f018d2c2f7114c5d8c308d0abfc698d8c9a6df30dce3bbc46f953f50fdc2619a01cead882816ecd4
+Y = 003d2d1b7d9baaa2a110d1d8317a39d68478b5c582d02824f0dd71dbd98a26cbde556bd0f293cdec9e2b9523a34591ce1a5f9e76712a5ddefc7b5c6b8bc90525251b
+
+Curve = P-521
+# N = 8
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008
+X = 000822c40fb6301f7262a8348396b010e25bd4e29d8a9b003e0a8b8a3b05f826298f5bfea5b8579f49f08b598c1bc8d79e1ab56289b5a6f4040586f9ea54aa78ce68
+Y = 016331911d5542fc482048fdab6e78853b9a44f8ede9e2c0715b5083de610677a8f189e9c0aa5911b4bff0ba0df065c578699f3ba940094713538ad642f11f17801c
+
+Curve = P-521
+# N = 9
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009
+X = 01585389e359e1e21826a2f5bf157156d488ed34541b988746992c4ab145b8c6b6657429e1396134da35f3c556df725a318f4f50babd85cd28661f45627967cbe207
+Y = 002a2e618c9a8aedf39f0b55557a27ae938e3088a654ee1cebb6c825ba263ddb446e0d69e5756057ac840ff56ecf4abfd87d736c2ae928880f343aa0ea86b9ad2a4e
+
+Curve = P-521
+# N = 10
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a
+X = 0190eb8f22bda61f281dfcfe7bb6721ec4cd901d879ac09ac7c34a9246b11ada8910a2c7c178fcc263299daa4da9842093f37c2e411f1a8e819a87ff09a04f2f3320
+Y = 01eb5d96b8491614ba9dbaeab3b0ca2ba760c2eeb2144251b20ba97fd78a62ef62d2bf5349d44d9864bb536f6163dc57ebeff3689639739faa172954bc98135ec759
+
+Curve = P-521
+# N = 11
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b
+X = 008a75841259fdedff546f1a39573b4315cfed5dc7ed7c17849543ef2c54f2991652f3dbc5332663da1bd19b1aebe3191085015c024fa4c9a902ecc0e02dda0cdb9a
+Y = 0096fb303fcbba2129849d0ca877054fb2293add566210bd0493ed2e95d4e0b9b82b1bc8a90e8b42a4ab3892331914a95336dcac80e3f4819b5d58874f92ce48c808
+
+Curve = P-521
+# N = 12
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c
+X = 01c0d9dcec93f8221c5de4fae9749c7fde1e81874157958457b6107cf7a5967713a644e90b7c3fb81b31477fee9a60e938013774c75c530928b17be69571bf842d8c
+Y = 014048b5946a4927c0fe3ce1d103a682ca4763fe65ab71494da45e404abf6a17c097d6d18843d86fcdb6cc10a6f951b9b630884ba72224f5ae6c79e7b1a3281b17f0
+
+Curve = P-521
+# N = 13
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d
+X = 007e3e98f984c396ad9cd7865d2b4924861a93f736cde1b4c2384eedd2beaf5b866132c45908e03c996a3550a5e79ab88ee94bec3b00ab38eff81887848d32fbcda7
+Y = 0108ee58eb6d781feda91a1926daa3ed5a08ced50a386d5421c69c7a67ae5c1e212ac1bd5d5838bc763f26dfdd351cbfbbc36199eaaf9117e9f7291a01fb022a71c9
+
+Curve = P-521
+# N = 14
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e
+X = 01875bc7dc551b1b65a9e1b8ccfaaf84ded1958b401494116a2fd4fb0babe0b3199974fc06c8b897222d79df3e4b7bc744aa6767f6b812efbf5d2c9e682dd3432d74
+Y = 005ca4923575dacb5bd2d66290bbabb4bdfb8470122b8e51826a0847ce9b86d7ed62d07781b1b4f3584c11e89bf1d133dc0d5b690f53a87c84be41669f852700d54a
+
+Curve = P-521
+# N = 15
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f
+X = 006b6ad89abcb92465f041558fc546d4300fb8fbcc30b40a0852d697b532df128e11b91cce27dbd00ffe7875bd1c8fc0331d9b8d96981e3f92bde9afe337bcb8db55
+Y = 01b468da271571391d6a7ce64d2333edbf63df0496a9bad20cba4b62106997485ed57e9062c899470a802148e2232c96c99246fd90cc446abdd956343480a1475465
+
+Curve = P-521
+# N = 16
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010
+X = 01d17d10d8a89c8ad05dda97da26ac743b0b2a87f66192fd3f3dd632f8d20b188a52943ff18861ca00a0e5965da7985630df0dbf5c8007dcdc533a6c508f81a8402f
+Y = 007a37343c582d77001fc714b18d3d3e69721335e4c3b800d50ec7ca30c94b6b82c1c182e1398db547aa0b3075ac9d9988529e3004d28d18633352e272f89bc73abe
+
+Curve = P-521
+# N = 17
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011
+X = 01b00ddb707f130eda13a0b874645923906a99ee9e269fa2b3b4d66524f269250858760a69e674fe0287df4e799b5681380ff8c3042af0d1a41076f817a853110ae0
+Y = 0085683f1d7db16576dbc111d4e4aeddd106b799534cf69910a98d68ac2b22a1323df9da564ef6dd0bf0d2f6757f16adf420e6905594c2b755f535b9cb7c70e64647
+
+Curve = P-521
+# N = 18
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012
+X = 01bc33425e72a12779eacb2edcc5b63d1281f7e86dbc7bf99a7abd0cfe367de4666d6edbb8525bffe5222f0702c3096dec0884ce572f5a15c423fdf44d01dd99c61d
+Y = 010d06e999885b63535de3e74d33d9e63d024fb07ce0d196f2552c8e4a00ac84c044234aeb201f7a9133915d1b4b45209b9da79fe15b19f84fd135d841e2d8f9a86a
+
+Curve = P-521
+# N = 19
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013
+X = 00998dcce486419c3487c0f948c2d5a1a07245b77e0755df547efff0acdb3790e7f1fa3b3096362669679232557d7a45970dfecf431e725bbde478ff0b2418d6a19b
+Y = 0137d5da0626a021ed5cc3942497535b245d67d28aee2b7bcf4acc50eee36545772773ad963ff2eb8cf9b0ec39991631c377f5a4d89ea9fbfe44a9091a695bfd0575
+
+Curve = P-521
+# N = 20
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014
+X = 018bdd7f1b889598a4653deeae39cc6f8cc2bd767c2ab0d93fb12e968fbed342b51709506339cb1049cb11dd48b9bdb3cd5cad792e43b74e16d8e2603bfb11b0344f
+Y = 00c5aadbe63f68ca5b6b6908296959bf0af89ee7f52b410b9444546c550952d311204da3bdddc6d4eae7edfaec1030da8ef837ccb22eee9cfc94dd3287fed0990f94
+
+Curve = P-521
+# N = 21
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015
+X = 01a1cbb2c11a742bd2fb3cc8550859ed3b10268bb98c2ed15e9819523e759c467fa946257eae4d62a309d9497eaed827d75b37ac920393a46d2d42ef399693c8c9ed
+Y = 011a209d7d4f8eeb3d482c12da7c5e40ce62e83c0059c5193e6c180a296f6bafa7f7df741a53da483295beb43a372c63eec57c9b0f17649ccb61e60bc43c9cba4df5
+
+Curve = P-521
+# N = 22
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016
+X = 009700ce6190c6d36ca5f1f6e66dc1eae621a7facca319d4b7aabde3122096c4089f74cbfe1018ffcd40adfffcca8b28ca1f904b3a12cae0af934e38650bb6f5a561
+Y = 01fb78827e13569356b061c78fad62100104be4a8d24e415f9c195e0fd06c5b46824f40ac9cdadfe028a2f22ec132ed14e5c5c43427efea6210d64319ad5a535acad
+
+Curve = P-521
+# N = 23
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017
+X = 01ae0b275d7290159376db1cacec5f547b8eee7a39ba785fb282490d234d0cdd45101f6f83fc9af5b0afe9e3f8e9a5ec53e207e1f1ac26ae5806a1c6a5ece2af535c
+Y = 00f2c97a825e5385380668a2858fc068471c7d759ff890d05832b431647844c2dc0e10843361ee97fcf43c27b27bb07dd0c2213b4450a8d23856d815c3536fa0d000
+
+Curve = P-521
+# N = 24
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018
+X = 00968e98d1008e9d525db447ce5d4930becf0e49a0e6ec40736691391a8862c2cd7f93ad7a9b2d0e4f666fdefaa4a86f6559c710838fa0a4198f44a18c28b69bcef2
+Y = 01e1a7e96f293f75117ce44476658a352aa7a555cd2f64a2b032b4cd2b81880aa962a48f492cf3d075368385e09fa134f7930575ce65dd7dd9fd8a0b537a0b446729
+
+Curve = P-521
+# N = 25
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000019
+X = 0154e84c6d5c5a9a1834a35874a6f5dff9d20073102651b107b11c772c8c5499994aa91856917c36ee4d56e87e2aa648ff27e41e0eb1c25d3fb13f8c2460bf70ace0
+Y = 00cd0fdce9171910473ae22a28f80bb60d3f15a923eb0022a0c7f66c2888151666a6dee3543572fbc1a0d1e2370a6a5972f5eede2a54672e6b6d4325bce404c78230
+
+Curve = P-521
+# N = 26
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a
+X = 017b61bd55cc8b533222d9857bb0c04dcd1331a02407e9a8576609bc2cbefa11d6aef686bfc27593b717007102d5dd038ed768dd29c10c73e41060d9e9a7e8c685c6
+Y = 01c34da05ea4b9de3bbea0196c0682be4633c8b4ac79f5a29ba2cbdc724709e1f426b4ddb8a4191a4648d74b5b2ac347d1335b8bff6c058ff572e74aacc5b9b4844b
+
+Curve = P-521
+# N = 27
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001b
+X = 0160373edf8218f9b6a762a4d4eb889e646f8739535d0e4f862c33f35187e135854d80b2123da719d48351353aeda0d3163cb215604492ec4568357643017002d68b
+Y = 00f1597050014dcfe1c5e5828401ac06a3fa9fd193c5cf52c3bb4a56f78e1a1b22011efa491ed92ebc5413b874f4a8bb572e463ffe709d45acb3f3e6aeca5d90b740
+
+Curve = P-521
+# N = 28
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c
+X = 019195646effed8e5f6fec5c29642dd68d1a988bb828d895ed5d116d7f87032133e2949da6c395738534b93220fe2ad07f0b291adc92433ee2dee160709ed9985b0c
+Y = 0177acd53b00c9f29f3ece28b4724f834f49606d3f34656a52ef5443c5d9216ae388b345b828c8b09a2b2e495cf2adcdd6b5886f4ded1741425ac31c832ba74eed38
+
+Curve = P-521
+# N = 29
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001d
+X = 0174c644d6c94b68287db3c1fbfcb65a085ff9f45131e86265ec28bef38f7664a1305ca9bc06876d72914003ab8e847ffb9ef33d8595d51f6d962c3927618eda25dc
+Y = 011af3a7c2f87f419e6805acc95b41b7b7820233ef8fcb6441fcb5cf5eb795ad34b7be0e21952ce0d90b50c2732d706d303f0679927c26ebbfbd187bbbc4821a0c30
+
+Curve = P-521
+# N = 30
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e
+X = 00d087d70d11074b36bb0b6913261570a6b33cf015e1f913a610ea52dbcbae2a3e4435573f35d14754c6352756cc169eac6bf7d9b10f1b0af5956117fab72ec4b081
+Y = 00c4d07f8c3cafdc1636811d7b95a6ac2dcebcde1cd94afbdbd3e47015660d29f15354d5b99d1d7d4adaf279efee5d860be9069edd46ff01cfc7b64d6af6579dbed3
+
+Curve = P-521
+# N = 31
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001f
+X = 00d8e9920cf30f0c6615006a58cdb7307b7db574589657c2a6617260a83ca5e7726cd65543a904c9d429fc14c1ac09cd6b220dcfb5e488e248122257d0e0c16a8803
+Y = 0127b023b5454a663987df09c13a214a30ec8b5406328f10c8060aefb72cbed1aa30f76b8c3244d14790139a868cae4cc263aa1bd97c7b54318aca4677c739792d19
+
+Curve = P-521
+# N = 32
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020
+X = 0166ba3596d20a3a469443707af94ba15b343e3e16654e068038dba7ecefb9e5ebd6ea04a35dc73596ec67d69bd6ba5d1f949cf7475cd6c5c78247915ab876e56a9e
+Y = 00477b0ff4d1940ab8111635e75ff3e08268ff7bd8bf5ff01967c1df01c65c2dd77de204cdb818cdd6b9b74de1c7ea0f36dfcd98c965ab96163695ca9a9914a156aa
+
+Curve = P-521
+# N = 33
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000021
+X = 00284195f0978fb969e68c76eb4e3c76f58e52086d482be92613f381421a74236df0abdbea7e2b77ef1ae9a519a57aa53ac2a5ec59186b2ed12d5ea2e1fc649f308d
+Y = 007e43eb08c656dc636b7b7a3bc869056d3a24d513abe063c6639e016769614ac5f2e7656ecbf3d138bf00bd7216c16deb3a88effd5c228b58f36be95a3dd3e11c4d
+
+Curve = P-521
+# N = 34
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022
+X = 0122f66451d0843fb59448c58962f5b7c130eb8db26b14dbf8bf0e7d84e588581cdea866a98b697d432cc1f1f8993db2173b55ac0435b8317a8ddfeab253d54e4d87
+Y = 01bed137b942249932f3c1f12141aee1538aa373f5aee0a89a48d357d7c04965b0515097293e4f87a6a413184d9be8ea91406baa5223db7571bcda9dba82fd9a06dc
+
+Curve = P-521
+# N = 35
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023
+X = 00ddc300757549630a78398b62069e0ba392a267a642b593e0bfc4a780b56f97392bb4806c84fda74023ee4a618608f6b2cea92ff614b5dcc8d8dc1039c9ccd7d718
+Y = 00c1bd2d07f6ac7fc5cc1b83431f0c30dbbfa510936cb5d85bcf462796591a31db509ab1178bd2c701425c212522ee69e797deba4db422640a4d3eb1d3ef241e07f4
+
+Curve = P-521
+# N = 36
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024
+X = 01ad81c98659bd21e082514d5e71894c417b2a25afe471eb8ad9e81a91dac8198aa9f385da9cc679bb96e724672821b585e05323bdc821e585edae56cbf798bd6ef0
+Y = 01217026e6cf8e6fc4e761aeda5705b3c0f8ca7f475441227b9761285bc6dc8f01af1af50b0bb140013a75db963d8698121dd2c4ba1759a98b43ac7712f8455c99ef
+
+Curve = P-521
+# N = 37
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025
+X = 00944f64a6c21832b67139e798352ded5867c35c5d56c1d59e4229ed0ae6af9d5749bd445763a28856040e58e26ee0980df28c64e76ae4780273f1ac4d59b557a36f
+Y = 0150b7ee1b02028ab7410c4b9624f26cb192fe4e6ff21865f85926317da6b7991305dcbdbc2471c83f81b85c564995a057c331a4be4056988296312bf98394fb2a03
+
+Curve = P-521
+# N = 38
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026
+X = 0195aeb1530c7d932a18922563d71ef6e7449078207b610c2c77690815bcef8f312718413823ed8d4ba112ac2ecc9d4e688346f120cb19ae965d853028d72a5f4a8b
+Y = 00e0c42d3cc093242000c0ec0975884bb0308611d8bd49b6090a06c5bdf7d0e1544851f9ba596291ef1ee3e3c9a002b7985ba29e51d193b701e0c87e1acd797bd130
+
+Curve = P-521
+# N = 39
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000027
+X = 0124a0b8f411fbad60755264126356a499029e9661a49b5b907238d9fd62359c6ea7256b0cc58626a1e2ac0bf434e5fa31795b4fa1d48083af670b704119ee33b77c
+Y = 001029616edc7335dce3602a9a406bbd399c68937baa8796154cdc0b1240c690db4818dc59feb96825aaa3caf2415944e762f212e74b698e40abd8dcdc61228b61a6
+
+Curve = P-521
+# N = 40
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028
+X = 002efdef97e46cd544553a0c67f41886ad969f67883679409022c4ad6090a169b596f85d832dc9767b2bb513eb4d0d01e18f067fffb5ac53dbcfaf456a57824c9d93
+Y = 00d88e2e3fdd283592d6c4c2a4687e65a6a823ffc6106dff96f75bb3141d0df516fe46a5357b21dc22404f4ef79e44aa97b22c101fec75d81e09b591f36738ae8e5c
+
+Curve = P-521
+# N = 41
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029
+X = 0175a140ed79e85e24a763ebfd9d2883082552a523e4b28998a685b85f23864a60c816b931eaf495ccce4c08c3ddc8297bfaddfda1a522cc2af68e00ce952624381e
+Y = 01b09696d71855e2d4ed36f21343ca399be7ab59e580e9ee563223de821b22c82111b39e0e11ecf327da052a6e551fa28ebdf75dd758e7f3a3ecebeb760ec1028ecf
+
+Curve = P-521
+# N = 42
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a
+X = 0161960dcd7bd7263ed37a0a1c0aa146f918874f472a2a5de6f2f5633364979e0bda2868fa8595d78243ea20d4e83c72305e420bebfa3767dcd4b7902612a9491855
+Y = 016ac1cfdd433815668a5c6ae0d1031bc121a00e6a6b58d1eec42da602f01cc43b7ef728d67c4e39de86324cba6a2c4cce08414fdd6ad7d0722338a50e352ad521ef
+
+Curve = P-521
+# N = 43
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002b
+X = 018c0148a165ec58e4fed55022d90544d8a070678aa2ec1419af8ef0f94438fea396fc66ad7aed7d37dda3a74e7a9b3d85ca51f0b62fdee07d20713e3083224f497e
+Y = 010abbaa1f099e78869aebf7a83c7aa3bf242677e91db1d144cd7a3037819f1a0bec67fd6098879b1cf1932d602b547ce17a94edb92f76b688d2895829067683adbf
+
+Curve = P-521
+# N = 44
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002c
+X = 013fdb51df11f0b29b485f0c48a04cca16cfe1cecbe9fd57f6507c3cfcbef88c88cf761e3e73e6509ec7e77fffe912d2b367b25aa02cb1d33a5378f253cdcde738d2
+Y = 01d14c8c184a7228a7034e4f65b3d0338f667aac908b39acf39c9ebedc0452b7c2f2a4460186aa2271d357733ea23d7284a8a123424f99a20b5242343b5cbafa661a
+
+Curve = P-521
+# N = 45
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002d
+X = 004969d186aca09e53b879596b8fff2bc0207a58f7f28c147cc07b2df5e3f197286779189b7df8a1f2d9dc8ea1ace5703f0fc2954607b66b70c4a32dec600fc95c1a
+Y = 01e81ec9b50cd8d3847d4d6ac21f3149fc7b15862a423270884135584a1bbcdb40a9b8d5b2802eadae85e6ed9e879be328e13463f5d90b37564f9498a7cd000903a9
+
+Curve = P-521
+# N = 46
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e
+X = 00bbdb162d8284a910021998e2d14f33a8c51a9cfb9a69a8fc5709f753aaf1c4d248a6ddb5626540f81d07c09231d2ec1549f672b6d2bd57d22f64f2ae8093e738a5
+Y = 013b86f0d5921216efe01fe9c7cabc10b00ab81c9fbd9674149d2ece424b786f6c372a1831112f54132d7d3af42dc8cd7e17b7ec80b09fa59f0e42c142895961259a
+
+Curve = P-521
+# N = 47
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002f
+X = 00afe31f8907048afd5f9cf5083ecc35882ce4e4fe2714033ff897233106c71dd0b2381864a0b9e922ac9cee75a3a9c4dd660a56a130d1ecbb672fda63c9abd59d11
+Y = 0012f95dc8657275fe9db4290cbbb54ff69a605f079349209f88ecea7f3276f064979276080b904982a6ebb760f478d825e711ca41599f10673bd3065d2f1d90e1d6
+
+Curve = P-521
+# N = 48
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030
+X = 01fb35de3b21557462ac8158e5caec62c8ccae7d6d6672102c334b3cc8a5803e72f42da0980f3f6fbfacdedc21b10ff08ee6641752bd214aea2c87027d612ad879ad
+Y = 018d34a5ac1587992deda855b9ec4bb3f5c176f27fc94d09e2cc871294f66cc2e1bae6214d64a1d97e37b7c142e0fb0e3c28596f24804841cae7b1958193d256d46b
+
+Curve = P-521
+# N = 49
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031
+X = 00a5cb98fa3c0b8c1d57cba40a63bbaba0d39d45c347ae499839f581b8b111dea9eb6bc2a2df52f6284291d8c84e2e345fa87258dab1ac4c04ca0c8cb45049efc0ad
+Y = 0015dc95654090d77b971409b01bf72e151b749ee467877e5b7eb072c39d9da8bf835dd9775543d575c20c10f2ceebb72bb44b963fbfb0b88b1d0b9bf46a2c8884b4
+
+Curve = P-521
+# N = 50
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000032
+X = 017176204957627b7a120baf0dbb1aa3f9ca5312b292e34a0cfbd8384cf1be365bc684804ab26d84fe02250a859beaced3f356b6ddab593aebf35386773de84d4766
+Y = 01ac713d5c2ffb0e111983e07ea5f688b03dd3032d3a9450b50c5def1db4859b504caf8c1321bb6c8d5fad93d2e5b9d0e75336298e21939f704f3f16ac6addc84f8f
+
+Curve = P-521
+# N = 51
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000033
+X = 0168395ba51e278415a2025d93b68145f3ccfdf9f5bde34fe9ba3ba316cbf9beea26c2edfe6af07390df1321ae1b1054cbc0fba689ef1d7be2dda8d916fffbcc9504
+Y = 0071cc10f3ca041a245639d9531942d3f57952dd878f21c480ce24e5b174adeb9b3c97bc2b68badb600c849c36096e3aeba50600aabed3a89e188eb9c45edd5c087b
+
+Curve = P-521
+# N = 52
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034
+X = 001f32e875ce65d1e6d4c39a55b518749158a4dae03e0c1b4b4a58aef6be769f0693b9259354dcee33a4f00784311b6e5993955114f2afcab7a186177e368b29f6f3
+Y = 005a3c8e76fb7849180b895ea8b22ee1a6fc2cbf93bbae0f4ad4a0c126d318c397911e73a061b8098a91112577769cd77ef2bd6b45f989f292da9301992d481b07f8
+
+Curve = P-521
+# N = 53
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000035
+X = 0143f6e249195ee693f77b3d0ffd310306dff8688be916895fb727e82f6f948100c44e210e637209a78ed3af581fba4fe12b08153da9c98808166285684cccb69906
+Y = 01053e8fcc9618eb2a74c5611a02575109877dc73fdde42c216935437e8053d10cb14fdf64f503cf3bb30f6a7a9de3b4cf8c040a3dfbc4abee6afd6ddaddd40c7861
+
+Curve = P-521
+# N = 54
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036
+X = 01938e65f2a40e6899c6414997e998e0e3e1cb09728861ea138fc6d866fdc6c98505393cf55982451c97dac4214e4dbf052bf707cab63228fdfcf5ae2048a0ce100c
+Y = 0163d556dd0941ce794e9c2868a692e89dbf943485186e2074e8222e0ed99fea4bd0c6069fa8017db8bec972b99ee0d7fcbc0f607d677492659bfa47b98bb8d1b411
+
+Curve = P-521
+# N = 55
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000037
+X = 004b52fc4b6d310ce7c4b551e4155c6daca97cb03e9fd9d0a79d6472d4028e8da1a18cca93917cad27e6be17486b1e0b549a7fe9ab4bda96ac4e84ad7ccebd470f5e
+Y = 003585e54fe81461ae21385ea7907a1a7b2e619f44311a16a0b600fb114a7dbae15510aa85895c5a084cd69609e345b53586fa03a23006a096ea7a196cd230a36ef2
+
+Curve = P-521
+# N = 56
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000038
+X = 003cd775038527f32baf7e9056e95b0cbef7638c12398e4b8b019cc29b3435be97f601378e253fef51d25730e56267acca241df04ea2e96c1840b3f739d5ae2df998
+Y = 00789bf7cf42095c5b1770e1a3561fc3e1232b0430e114f67a397c1e5b54987f4a28b52a737cbaa0ffa2c431863c1a8cbf15eba60fb5d8b4723dc10d9706f4083cba
+
+Curve = P-521
+# N = 57
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000039
+X = 00dc53c3e7fcf3c902e04463da75efb25ffa5a8defe72e6dbf85ef3c6d77a521b9f84af300bbde9118b2f66fd5bc64b8a5208372c8fff95c84503475330a4e9a13e2
+Y = 0074e88fccd4fdbd992b68073ee6c4d4f8f7b13d0dd2caf9d989b62e7eb390dff3ea3482530d0d3bd86a4a3f82056a929f73a9493190c62a553233ad7f7fd9c4248f
+
+Curve = P-521
+# N = 58
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a
+X = 008bc46df1c09851ab92d53b6ad821b5026be61385c801f5277c9871b54c6764d3fdb96a728ad56c650d342a03e174a3106a5479d3ccb04647ad0f583210d81ab70d
+Y = 01d948ff92784e9946a27a4c58d40bfb0e0b765073f1f9a731aa52b53e4fe686134fee784bec8fca81a73b8ac3a45ca1b766cdec69190bf94d71fa08b29292c1205f
+
+Curve = P-521
+# N = 59
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003b
+X = 0035aeb454ad31876773063c60342df29eadc7223c5d98901999aae5c2934c222920055693c9b1344c691a90342d64373a8acba8524ec347208863be8a26eb16686b
+Y = 00187ecbec147e7e43b4db0b0ca0aff1ba7f15a48db3660903f4e22f2ef3cb6efd45b8cf8c44bc83d0b8c9fd5fddd64ffec3fd82c38cfaffe51acf4aa03c5381fa2e
+
+Curve = P-521
+# N = 60
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003c
+X = 00038a508e954435eff6ccb82b562ed32ff236f33caef52de9fdf79836e37bbe118392681661adc786c57fb6bf92d04b42fc051c3f6061c252749fd17ffbfca45bdc
+Y = 008dbd87d8b1e7bd4d2adb7a7399b931e7169b0ecf8e37baa0e9997df1a529560a5a5edb1e7a605abfd04b1ccdfa683285b4d748f73799f3e5d4f8464ad3910e9522
+
+Curve = P-521
+# N = 61
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003d
+X = 0115544c4a011407425c92ca7c732a1c7d8f8b6cd17d5b660d1a4cd724b1be8b17177193c11a77dc0b39a5e7fce59a7b32d7952bad1671543c41cb53d8cfcfc376a1
+Y = 01153df9c6c0ac6485b307996d2a399c872c79af485fef422cbfec097a3aed58c6a003f78d54b7f553a8a834ff603afa032b56f22ee9c3fe5e24b8eff8cd4a17604b
+
+Curve = P-521
+# N = 62
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e
+X = 01f605dada534c5c8ae020f6ed49f27734e2378b0b7bc177aeaf943ae59581dd5885a38bf246fec516fd213f3fe32bfd4e19f0a8c971ef2a16969627fe31114dc85e
+Y = 014ff96d82698b78d305a2252c7a4be38a37f2b0afd6935f4aaa50e685ccd164a2206284a831f6b296eacb156b6e7671eb7adda2d7e072a578a319f1002224aa57b5
+
+Curve = P-521
+# N = 63
+N = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003f
+X = 01c132753b64640c457fe82f799acb0a6e8e1ca21b5affa0ddc1e7f54fe4d51b08453ae99661308e125ec63996847586265e75af7d025770ac8d0f5beb6fce8888e5
+Y = 015347e184197a0538176d81ac89b205d7961a9e093286414006595e8c353aa2238005d3dbdcec1896bc13f78f82f0071283af657b5bf664a2ace9d15ad2a03dba15
+
+Curve = P-521
+# N = 64
+N = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040
+X = 01ab9aa17dce1112ecd14f3d7c0392fec2a67ebdbba81860bbacb614b9ccf8872d271bebd3c5efda3773a7c02c1603e7001df5aab8029a04fd41b53dc38ce320f742
+Y = 00748d70eb848e920573aa10217c57b9586d9bb1cc8b2fb1dc1d0c63ba369e87ab8bac165ba1508d4b10f4a7b9e3af958043c1c1a5dba0653dd45af17058a5f8df5b
+
diff --git a/src/crypto/fipsmodule/ec/ec_test.cc b/src/crypto/fipsmodule/ec/ec_test.cc
new file mode 100644
index 0000000..a40dd16
--- /dev/null
+++ b/src/crypto/fipsmodule/ec/ec_test.cc
@@ -0,0 +1,1430 @@
+/* Copyright (c) 2014, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <vector>
+
+#include <gtest/gtest.h>
+
+#include <openssl/bn.h>
+#include <openssl/bytestring.h>
+#include <openssl/crypto.h>
+#include <openssl/ec_key.h>
+#include <openssl/err.h>
+#include <openssl/mem.h>
+#include <openssl/nid.h>
+#include <openssl/obj.h>
+#include <openssl/span.h>
+
+#include "../../ec_extra/internal.h"
+#include "../../test/file_test.h"
+#include "../../test/test_util.h"
+#include "../bn/internal.h"
+#include "internal.h"
+
+
+// kECKeyWithoutPublic is an ECPrivateKey with the optional publicKey field
+// omitted.
+static const uint8_t kECKeyWithoutPublic[] = {
+ 0x30, 0x31, 0x02, 0x01, 0x01, 0x04, 0x20, 0xc6, 0xc1, 0xaa, 0xda, 0x15, 0xb0,
+ 0x76, 0x61, 0xf8, 0x14, 0x2c, 0x6c, 0xaf, 0x0f, 0xdb, 0x24, 0x1a, 0xff, 0x2e,
+ 0xfe, 0x46, 0xc0, 0x93, 0x8b, 0x74, 0xf2, 0xbc, 0xc5, 0x30, 0x52, 0xb0, 0x77,
+ 0xa0, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07,
+};
+
+// kECKeySpecifiedCurve is the above key with P-256's parameters explicitly
+// spelled out rather than using a named curve.
+static const uint8_t kECKeySpecifiedCurve[] = {
+ 0x30, 0x82, 0x01, 0x22, 0x02, 0x01, 0x01, 0x04, 0x20, 0xc6, 0xc1, 0xaa,
+ 0xda, 0x15, 0xb0, 0x76, 0x61, 0xf8, 0x14, 0x2c, 0x6c, 0xaf, 0x0f, 0xdb,
+ 0x24, 0x1a, 0xff, 0x2e, 0xfe, 0x46, 0xc0, 0x93, 0x8b, 0x74, 0xf2, 0xbc,
+ 0xc5, 0x30, 0x52, 0xb0, 0x77, 0xa0, 0x81, 0xfa, 0x30, 0x81, 0xf7, 0x02,
+ 0x01, 0x01, 0x30, 0x2c, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01,
+ 0x01, 0x02, 0x21, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x30, 0x5b, 0x04, 0x20, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
+ 0x04, 0x20, 0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7, 0xb3, 0xeb,
+ 0xbd, 0x55, 0x76, 0x98, 0x86, 0xbc, 0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53,
+ 0xb0, 0xf6, 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b, 0x03, 0x15,
+ 0x00, 0xc4, 0x9d, 0x36, 0x08, 0x86, 0xe7, 0x04, 0x93, 0x6a, 0x66, 0x78,
+ 0xe1, 0x13, 0x9d, 0x26, 0xb7, 0x81, 0x9f, 0x7e, 0x90, 0x04, 0x41, 0x04,
+ 0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc, 0xe6, 0xe5,
+ 0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0,
+ 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96, 0x4f, 0xe3, 0x42, 0xe2,
+ 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16,
+ 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68,
+ 0x37, 0xbf, 0x51, 0xf5, 0x02, 0x21, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbc,
+ 0xe6, 0xfa, 0xad, 0xa7, 0x17, 0x9e, 0x84, 0xf3, 0xb9, 0xca, 0xc2, 0xfc,
+ 0x63, 0x25, 0x51, 0x02, 0x01, 0x01,
+};
+
+// kECKeyMissingZeros is an ECPrivateKey containing a degenerate P-256 key where
+// the private key is one. The private key is incorrectly encoded without zero
+// padding.
+static const uint8_t kECKeyMissingZeros[] = {
+ 0x30, 0x58, 0x02, 0x01, 0x01, 0x04, 0x01, 0x01, 0xa0, 0x0a, 0x06, 0x08, 0x2a,
+ 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0xa1, 0x44, 0x03, 0x42, 0x00, 0x04,
+ 0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc, 0xe6, 0xe5, 0x63,
+ 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0, 0xf4, 0xa1,
+ 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96, 0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f,
+ 0x9b, 0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57,
+ 0x6b, 0x31, 0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5,
+};
+
+// kECKeyMissingZeros is an ECPrivateKey containing a degenerate P-256 key where
+// the private key is one. The private key is encoded with the required zero
+// padding.
+static const uint8_t kECKeyWithZeros[] = {
+ 0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0xa0, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0xa1,
+ 0x44, 0x03, 0x42, 0x00, 0x04, 0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47,
+ 0xf8, 0xbc, 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81, 0x2d,
+ 0xeb, 0x33, 0xa0, 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96, 0x4f, 0xe3,
+ 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e,
+ 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68,
+ 0x37, 0xbf, 0x51, 0xf5,
+};
+
+static const uint8_t kECKeyWithZerosPublic[] = {
+ 0x04, 0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc,
+ 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81, 0x2d,
+ 0xeb, 0x33, 0xa0, 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96,
+ 0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb,
+ 0x4a, 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31,
+ 0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5,
+};
+
+static const uint8_t kECKeyWithZerosRawPrivate[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
+
+// DecodeECPrivateKey decodes |in| as an ECPrivateKey structure and returns the
+// result or nullptr on error.
+static bssl::UniquePtr<EC_KEY> DecodeECPrivateKey(const uint8_t *in,
+ size_t in_len) {
+ CBS cbs;
+ CBS_init(&cbs, in, in_len);
+ bssl::UniquePtr<EC_KEY> ret(EC_KEY_parse_private_key(&cbs, NULL));
+ if (!ret || CBS_len(&cbs) != 0) {
+ return nullptr;
+ }
+ return ret;
+}
+
+// EncodeECPrivateKey encodes |key| as an ECPrivateKey structure into |*out|. It
+// returns true on success or false on error.
+static bool EncodeECPrivateKey(std::vector<uint8_t> *out, const EC_KEY *key) {
+ bssl::ScopedCBB cbb;
+ uint8_t *der;
+ size_t der_len;
+ if (!CBB_init(cbb.get(), 0) ||
+ !EC_KEY_marshal_private_key(cbb.get(), key, EC_KEY_get_enc_flags(key)) ||
+ !CBB_finish(cbb.get(), &der, &der_len)) {
+ return false;
+ }
+ out->assign(der, der + der_len);
+ OPENSSL_free(der);
+ return true;
+}
+
+static bool EncodeECPoint(std::vector<uint8_t> *out, const EC_GROUP *group,
+ const EC_POINT *p, point_conversion_form_t form) {
+ size_t len = EC_POINT_point2oct(group, p, form, nullptr, 0, nullptr);
+ if (len == 0) {
+ return false;
+ }
+
+ out->resize(len);
+ len = EC_POINT_point2oct(group, p, form, out->data(), out->size(), nullptr);
+ if (len != out->size()) {
+ return false;
+ }
+
+ return true;
+}
+
+TEST(ECTest, Encoding) {
+ bssl::UniquePtr<EC_KEY> key =
+ DecodeECPrivateKey(kECKeyWithoutPublic, sizeof(kECKeyWithoutPublic));
+ ASSERT_TRUE(key);
+
+ // Test that the encoding round-trips.
+ std::vector<uint8_t> out;
+ ASSERT_TRUE(EncodeECPrivateKey(&out, key.get()));
+ EXPECT_EQ(Bytes(kECKeyWithoutPublic), Bytes(out.data(), out.size()));
+
+ const EC_POINT *pub_key = EC_KEY_get0_public_key(key.get());
+ ASSERT_TRUE(pub_key) << "Public key missing";
+
+ bssl::UniquePtr<BIGNUM> x(BN_new());
+ bssl::UniquePtr<BIGNUM> y(BN_new());
+ ASSERT_TRUE(x);
+ ASSERT_TRUE(y);
+ ASSERT_TRUE(EC_POINT_get_affine_coordinates_GFp(
+ EC_KEY_get0_group(key.get()), pub_key, x.get(), y.get(), NULL));
+ bssl::UniquePtr<char> x_hex(BN_bn2hex(x.get()));
+ bssl::UniquePtr<char> y_hex(BN_bn2hex(y.get()));
+ ASSERT_TRUE(x_hex);
+ ASSERT_TRUE(y_hex);
+
+ EXPECT_STREQ(
+ "c81561ecf2e54edefe6617db1c7a34a70744ddb261f269b83dacfcd2ade5a681",
+ x_hex.get());
+ EXPECT_STREQ(
+ "e0e2afa3f9b6abe4c698ef6495f1be49a3196c5056acb3763fe4507eec596e88",
+ y_hex.get());
+}
+
+TEST(ECTest, ZeroPadding) {
+ // Check that the correct encoding round-trips.
+ bssl::UniquePtr<EC_KEY> key =
+ DecodeECPrivateKey(kECKeyWithZeros, sizeof(kECKeyWithZeros));
+ ASSERT_TRUE(key);
+ std::vector<uint8_t> out;
+ EXPECT_TRUE(EncodeECPrivateKey(&out, key.get()));
+ EXPECT_EQ(Bytes(kECKeyWithZeros), Bytes(out.data(), out.size()));
+
+ // Check the private key encodes correctly, including with the leading zeros.
+ EXPECT_EQ(32u, EC_KEY_priv2oct(key.get(), nullptr, 0));
+ uint8_t buf[32];
+ ASSERT_EQ(32u, EC_KEY_priv2oct(key.get(), buf, sizeof(buf)));
+ EXPECT_EQ(Bytes(buf), Bytes(kECKeyWithZerosRawPrivate));
+
+ // Buffer too small.
+ EXPECT_EQ(0u, EC_KEY_priv2oct(key.get(), buf, sizeof(buf) - 1));
+
+ // Extra space in buffer.
+ uint8_t large_buf[33];
+ ASSERT_EQ(32u, EC_KEY_priv2oct(key.get(), large_buf, sizeof(large_buf)));
+ EXPECT_EQ(Bytes(buf), Bytes(kECKeyWithZerosRawPrivate));
+
+ // Allocating API.
+ uint8_t *buf_alloc;
+ size_t len = EC_KEY_priv2buf(key.get(), &buf_alloc);
+ ASSERT_GT(len, 0u);
+ bssl::UniquePtr<uint8_t> free_buf_alloc(buf_alloc);
+ EXPECT_EQ(Bytes(buf_alloc, len), Bytes(kECKeyWithZerosRawPrivate));
+
+ // Keys without leading zeros also parse, but they encode correctly.
+ key = DecodeECPrivateKey(kECKeyMissingZeros, sizeof(kECKeyMissingZeros));
+ ASSERT_TRUE(key);
+ EXPECT_TRUE(EncodeECPrivateKey(&out, key.get()));
+ EXPECT_EQ(Bytes(kECKeyWithZeros), Bytes(out.data(), out.size()));
+
+ // Test the key can be constructed with |EC_KEY_oct2*|.
+ key.reset(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
+ ASSERT_TRUE(key);
+ ASSERT_TRUE(EC_KEY_oct2key(key.get(), kECKeyWithZerosPublic,
+ sizeof(kECKeyWithZerosPublic), nullptr));
+ ASSERT_TRUE(EC_KEY_oct2priv(key.get(), kECKeyWithZerosRawPrivate,
+ sizeof(kECKeyWithZerosRawPrivate)));
+ EXPECT_TRUE(EncodeECPrivateKey(&out, key.get()));
+ EXPECT_EQ(Bytes(kECKeyWithZeros), Bytes(out.data(), out.size()));
+
+ // |EC_KEY_oct2priv|'s format is fixed-width and must match the group order.
+ key.reset(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
+ ASSERT_TRUE(key);
+ EXPECT_FALSE(EC_KEY_oct2priv(key.get(), kECKeyWithZerosRawPrivate + 1,
+ sizeof(kECKeyWithZerosRawPrivate) - 1));
+ uint8_t padded[sizeof(kECKeyWithZerosRawPrivate) + 1] = {0};
+ memcpy(padded + 1, kECKeyWithZerosRawPrivate,
+ sizeof(kECKeyWithZerosRawPrivate));
+ EXPECT_FALSE(EC_KEY_oct2priv(key.get(), padded, sizeof(padded)));
+}
+
+TEST(ECTest, SpecifiedCurve) {
+ // Test keys with specified curves may be decoded.
+ bssl::UniquePtr<EC_KEY> key =
+ DecodeECPrivateKey(kECKeySpecifiedCurve, sizeof(kECKeySpecifiedCurve));
+ ASSERT_TRUE(key);
+
+ // The group should have been interpreted as P-256.
+ EXPECT_EQ(NID_X9_62_prime256v1,
+ EC_GROUP_get_curve_name(EC_KEY_get0_group(key.get())));
+
+ // Encoding the key should still use named form.
+ std::vector<uint8_t> out;
+ EXPECT_TRUE(EncodeECPrivateKey(&out, key.get()));
+ EXPECT_EQ(Bytes(kECKeyWithoutPublic), Bytes(out.data(), out.size()));
+}
+
+TEST(ECTest, ArbitraryCurve) {
+ // Make a P-256 key and extract the affine coordinates.
+ bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
+ ASSERT_TRUE(key);
+ ASSERT_TRUE(EC_KEY_generate_key(key.get()));
+
+ // Make an arbitrary curve which is identical to P-256.
+ static const uint8_t kP[] = {
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ };
+ static const uint8_t kA[] = {
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
+ };
+ static const uint8_t kB[] = {
+ 0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7, 0xb3, 0xeb, 0xbd,
+ 0x55, 0x76, 0x98, 0x86, 0xbc, 0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53,
+ 0xb0, 0xf6, 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b,
+ };
+ static const uint8_t kX[] = {
+ 0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc, 0xe6,
+ 0xe5, 0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb,
+ 0x33, 0xa0, 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96,
+ };
+ static const uint8_t kY[] = {
+ 0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb,
+ 0x4a, 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31,
+ 0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5,
+ };
+ static const uint8_t kOrder[] = {
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xbc, 0xe6, 0xfa, 0xad, 0xa7, 0x17,
+ 0x9e, 0x84, 0xf3, 0xb9, 0xca, 0xc2, 0xfc, 0x63, 0x25, 0x51,
+ };
+ bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());
+ ASSERT_TRUE(ctx);
+ bssl::UniquePtr<BIGNUM> p(BN_bin2bn(kP, sizeof(kP), nullptr));
+ ASSERT_TRUE(p);
+ bssl::UniquePtr<BIGNUM> a(BN_bin2bn(kA, sizeof(kA), nullptr));
+ ASSERT_TRUE(a);
+ bssl::UniquePtr<BIGNUM> b(BN_bin2bn(kB, sizeof(kB), nullptr));
+ ASSERT_TRUE(b);
+ bssl::UniquePtr<BIGNUM> gx(BN_bin2bn(kX, sizeof(kX), nullptr));
+ ASSERT_TRUE(gx);
+ bssl::UniquePtr<BIGNUM> gy(BN_bin2bn(kY, sizeof(kY), nullptr));
+ ASSERT_TRUE(gy);
+ bssl::UniquePtr<BIGNUM> order(BN_bin2bn(kOrder, sizeof(kOrder), nullptr));
+ ASSERT_TRUE(order);
+
+ bssl::UniquePtr<EC_GROUP> group(
+ EC_GROUP_new_curve_GFp(p.get(), a.get(), b.get(), ctx.get()));
+ ASSERT_TRUE(group);
+ bssl::UniquePtr<EC_POINT> generator(EC_POINT_new(group.get()));
+ ASSERT_TRUE(generator);
+ ASSERT_TRUE(EC_POINT_set_affine_coordinates_GFp(
+ group.get(), generator.get(), gx.get(), gy.get(), ctx.get()));
+ ASSERT_TRUE(EC_GROUP_set_generator(group.get(), generator.get(), order.get(),
+ BN_value_one()));
+
+ // |group| should not have a curve name.
+ EXPECT_EQ(NID_undef, EC_GROUP_get_curve_name(group.get()));
+
+ // Copy |key| to |key2| using |group|.
+ bssl::UniquePtr<EC_KEY> key2(EC_KEY_new());
+ ASSERT_TRUE(key2);
+ bssl::UniquePtr<EC_POINT> point(EC_POINT_new(group.get()));
+ ASSERT_TRUE(point);
+ bssl::UniquePtr<BIGNUM> x(BN_new()), y(BN_new());
+ ASSERT_TRUE(x);
+ ASSERT_TRUE(EC_KEY_set_group(key2.get(), group.get()));
+ ASSERT_TRUE(
+ EC_KEY_set_private_key(key2.get(), EC_KEY_get0_private_key(key.get())));
+ ASSERT_TRUE(EC_POINT_get_affine_coordinates_GFp(
+ EC_KEY_get0_group(key.get()), EC_KEY_get0_public_key(key.get()), x.get(),
+ y.get(), nullptr));
+ ASSERT_TRUE(EC_POINT_set_affine_coordinates_GFp(group.get(), point.get(),
+ x.get(), y.get(), nullptr));
+ ASSERT_TRUE(EC_KEY_set_public_key(key2.get(), point.get()));
+
+ // The key must be valid according to the new group too.
+ EXPECT_TRUE(EC_KEY_check_key(key2.get()));
+
+ // Make a second instance of |group|.
+ bssl::UniquePtr<EC_GROUP> group2(
+ EC_GROUP_new_curve_GFp(p.get(), a.get(), b.get(), ctx.get()));
+ ASSERT_TRUE(group2);
+ bssl::UniquePtr<EC_POINT> generator2(EC_POINT_new(group2.get()));
+ ASSERT_TRUE(generator2);
+ ASSERT_TRUE(EC_POINT_set_affine_coordinates_GFp(
+ group2.get(), generator2.get(), gx.get(), gy.get(), ctx.get()));
+ ASSERT_TRUE(EC_GROUP_set_generator(group2.get(), generator2.get(),
+ order.get(), BN_value_one()));
+
+ EXPECT_EQ(0, EC_GROUP_cmp(group.get(), group.get(), NULL));
+ EXPECT_EQ(0, EC_GROUP_cmp(group2.get(), group.get(), NULL));
+
+ // group3 uses the wrong generator.
+ bssl::UniquePtr<EC_GROUP> group3(
+ EC_GROUP_new_curve_GFp(p.get(), a.get(), b.get(), ctx.get()));
+ ASSERT_TRUE(group3);
+ bssl::UniquePtr<EC_POINT> generator3(EC_POINT_new(group3.get()));
+ ASSERT_TRUE(generator3);
+ ASSERT_TRUE(EC_POINT_set_affine_coordinates_GFp(
+ group3.get(), generator3.get(), x.get(), y.get(), ctx.get()));
+ ASSERT_TRUE(EC_GROUP_set_generator(group3.get(), generator3.get(),
+ order.get(), BN_value_one()));
+
+ EXPECT_NE(0, EC_GROUP_cmp(group.get(), group3.get(), NULL));
+
+#if !defined(BORINGSSL_SHARED_LIBRARY)
+ // group4 has non-minimal components that do not fit in |EC_SCALAR| and the
+ // future |EC_FELEM|.
+ ASSERT_TRUE(bn_resize_words(p.get(), 32));
+ ASSERT_TRUE(bn_resize_words(a.get(), 32));
+ ASSERT_TRUE(bn_resize_words(b.get(), 32));
+ ASSERT_TRUE(bn_resize_words(gx.get(), 32));
+ ASSERT_TRUE(bn_resize_words(gy.get(), 32));
+ ASSERT_TRUE(bn_resize_words(order.get(), 32));
+
+ bssl::UniquePtr<EC_GROUP> group4(
+ EC_GROUP_new_curve_GFp(p.get(), a.get(), b.get(), ctx.get()));
+ ASSERT_TRUE(group4);
+ bssl::UniquePtr<EC_POINT> generator4(EC_POINT_new(group4.get()));
+ ASSERT_TRUE(generator4);
+ ASSERT_TRUE(EC_POINT_set_affine_coordinates_GFp(
+ group4.get(), generator4.get(), gx.get(), gy.get(), ctx.get()));
+ ASSERT_TRUE(EC_GROUP_set_generator(group4.get(), generator4.get(),
+ order.get(), BN_value_one()));
+
+ EXPECT_EQ(0, EC_GROUP_cmp(group.get(), group4.get(), NULL));
+#endif
+
+ // group5 is the same group, but the curve coefficients are passed in
+ // unreduced and the caller does not pass in a |BN_CTX|.
+ ASSERT_TRUE(BN_sub(a.get(), a.get(), p.get()));
+ ASSERT_TRUE(BN_add(b.get(), b.get(), p.get()));
+ bssl::UniquePtr<EC_GROUP> group5(
+ EC_GROUP_new_curve_GFp(p.get(), a.get(), b.get(), NULL));
+ ASSERT_TRUE(group5);
+ bssl::UniquePtr<EC_POINT> generator5(EC_POINT_new(group5.get()));
+ ASSERT_TRUE(generator5);
+ ASSERT_TRUE(EC_POINT_set_affine_coordinates_GFp(
+ group5.get(), generator5.get(), gx.get(), gy.get(), ctx.get()));
+ ASSERT_TRUE(EC_GROUP_set_generator(group5.get(), generator5.get(),
+ order.get(), BN_value_one()));
+
+ EXPECT_EQ(0, EC_GROUP_cmp(group.get(), group.get(), NULL));
+ EXPECT_EQ(0, EC_GROUP_cmp(group5.get(), group.get(), NULL));
+}
+
+TEST(ECTest, SetKeyWithoutGroup) {
+ bssl::UniquePtr<EC_KEY> key(EC_KEY_new());
+ ASSERT_TRUE(key);
+
+ // Private keys may not be configured without a group.
+ EXPECT_FALSE(EC_KEY_set_private_key(key.get(), BN_value_one()));
+
+ // Public keys may not be configured without a group.
+ bssl::UniquePtr<EC_GROUP> group(
+ EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
+ ASSERT_TRUE(group);
+ EXPECT_FALSE(
+ EC_KEY_set_public_key(key.get(), EC_GROUP_get0_generator(group.get())));
+}
+
+TEST(ECTest, SetNULLKey) {
+ bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
+ ASSERT_TRUE(key);
+
+ EXPECT_TRUE(EC_KEY_set_public_key(
+ key.get(), EC_GROUP_get0_generator(EC_KEY_get0_group(key.get()))));
+ EXPECT_TRUE(EC_KEY_get0_public_key(key.get()));
+
+ // Setting a NULL public-key should clear the public-key and return zero, in
+ // order to match OpenSSL behaviour exactly.
+ EXPECT_FALSE(EC_KEY_set_public_key(key.get(), nullptr));
+ EXPECT_FALSE(EC_KEY_get0_public_key(key.get()));
+}
+
+TEST(ECTest, GroupMismatch) {
+ bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(NID_secp384r1));
+ ASSERT_TRUE(key);
+ bssl::UniquePtr<EC_GROUP> p256(
+ EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
+ ASSERT_TRUE(p256);
+
+ // Changing a key's group is invalid.
+ EXPECT_FALSE(EC_KEY_set_group(key.get(), p256.get()));
+
+ // Configuring a public key with the wrong group is invalid.
+ EXPECT_FALSE(
+ EC_KEY_set_public_key(key.get(), EC_GROUP_get0_generator(p256.get())));
+}
+
+TEST(ECTest, EmptyKey) {
+ bssl::UniquePtr<EC_KEY> key(EC_KEY_new());
+ ASSERT_TRUE(key);
+ EXPECT_FALSE(EC_KEY_get0_group(key.get()));
+ EXPECT_FALSE(EC_KEY_get0_public_key(key.get()));
+ EXPECT_FALSE(EC_KEY_get0_private_key(key.get()));
+}
+
+static bssl::UniquePtr<BIGNUM> HexToBIGNUM(const char *hex) {
+ BIGNUM *bn = nullptr;
+ BN_hex2bn(&bn, hex);
+ return bssl::UniquePtr<BIGNUM>(bn);
+}
+
+// Test that point arithmetic works with custom curves using an arbitrary |a|,
+// rather than -3, as is common (and more efficient).
+TEST(ECTest, BrainpoolP256r1) {
+ static const char kP[] =
+ "a9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d1f6e5377";
+ static const char kA[] =
+ "7d5a0975fc2c3057eef67530417affe7fb8055c126dc5c6ce94a4b44f330b5d9";
+ static const char kB[] =
+ "26dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7e1ce6bccdc18ff8c07b6";
+ static const char kX[] =
+ "8bd2aeb9cb7e57cb2c4b482ffc81b7afb9de27e1e3bd23c23a4453bd9ace3262";
+ static const char kY[] =
+ "547ef835c3dac4fd97f8461a14611dc9c27745132ded8e545c1d54c72f046997";
+ static const char kN[] =
+ "a9fb57dba1eea9bc3e660a909d838d718c397aa3b561a6f7901e0e82974856a7";
+ static const char kD[] =
+ "0da21d76fed40dd82ac3314cce91abb585b5c4246e902b238a839609ea1e7ce1";
+ static const char kQX[] =
+ "3a55e0341cab50452fe27b8a87e4775dec7a9daca94b0d84ad1e9f85b53ea513";
+ static const char kQY[] =
+ "40088146b33bbbe81b092b41146774b35dd478cf056437cfb35ef0df2d269339";
+
+ bssl::UniquePtr<BIGNUM> p = HexToBIGNUM(kP), a = HexToBIGNUM(kA),
+ b = HexToBIGNUM(kB), x = HexToBIGNUM(kX),
+ y = HexToBIGNUM(kY), n = HexToBIGNUM(kN),
+ d = HexToBIGNUM(kD), qx = HexToBIGNUM(kQX),
+ qy = HexToBIGNUM(kQY);
+ ASSERT_TRUE(p && a && b && x && y && n && d && qx && qy);
+
+ bssl::UniquePtr<EC_GROUP> group(
+ EC_GROUP_new_curve_GFp(p.get(), a.get(), b.get(), nullptr));
+ ASSERT_TRUE(group);
+ bssl::UniquePtr<EC_POINT> g(EC_POINT_new(group.get()));
+ ASSERT_TRUE(g);
+ ASSERT_TRUE(EC_POINT_set_affine_coordinates_GFp(group.get(), g.get(), x.get(),
+ y.get(), nullptr));
+ ASSERT_TRUE(
+ EC_GROUP_set_generator(group.get(), g.get(), n.get(), BN_value_one()));
+
+ bssl::UniquePtr<EC_POINT> q(EC_POINT_new(group.get()));
+ ASSERT_TRUE(q);
+ ASSERT_TRUE(
+ EC_POINT_mul(group.get(), q.get(), d.get(), nullptr, nullptr, nullptr));
+ ASSERT_TRUE(EC_POINT_get_affine_coordinates_GFp(group.get(), q.get(), x.get(),
+ y.get(), nullptr));
+ EXPECT_EQ(0, BN_cmp(x.get(), qx.get()));
+ EXPECT_EQ(0, BN_cmp(y.get(), qy.get()));
+}
+
+class ECCurveTest : public testing::TestWithParam<int> {
+ public:
+ const EC_GROUP *group() const { return group_.get(); }
+
+ void SetUp() override {
+ group_.reset(EC_GROUP_new_by_curve_name(GetParam()));
+ ASSERT_TRUE(group_);
+ }
+
+ private:
+ bssl::UniquePtr<EC_GROUP> group_;
+};
+
+TEST_P(ECCurveTest, SetAffine) {
+ // Generate an EC_KEY.
+ bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(GetParam()));
+ ASSERT_TRUE(key);
+ ASSERT_TRUE(EC_KEY_generate_key(key.get()));
+
+ // Get the public key's coordinates.
+ bssl::UniquePtr<BIGNUM> x(BN_new());
+ ASSERT_TRUE(x);
+ bssl::UniquePtr<BIGNUM> y(BN_new());
+ ASSERT_TRUE(y);
+ bssl::UniquePtr<BIGNUM> p(BN_new());
+ ASSERT_TRUE(p);
+ EXPECT_TRUE(EC_POINT_get_affine_coordinates_GFp(
+ group(), EC_KEY_get0_public_key(key.get()), x.get(), y.get(), nullptr));
+ EXPECT_TRUE(
+ EC_GROUP_get_curve_GFp(group(), p.get(), nullptr, nullptr, nullptr));
+
+ // Points on the curve should be accepted.
+ auto point = bssl::UniquePtr<EC_POINT>(EC_POINT_new(group()));
+ ASSERT_TRUE(point);
+ EXPECT_TRUE(EC_POINT_set_affine_coordinates_GFp(group(), point.get(), x.get(),
+ y.get(), nullptr));
+
+ // Subtract one from |y| to make the point no longer on the curve.
+ EXPECT_TRUE(BN_sub(y.get(), y.get(), BN_value_one()));
+
+ // Points not on the curve should be rejected.
+ bssl::UniquePtr<EC_POINT> invalid_point(EC_POINT_new(group()));
+ ASSERT_TRUE(invalid_point);
+ EXPECT_FALSE(EC_POINT_set_affine_coordinates_GFp(group(), invalid_point.get(),
+ x.get(), y.get(), nullptr));
+
+ // Coordinates out of range should be rejected.
+ EXPECT_TRUE(BN_add(y.get(), y.get(), BN_value_one()));
+ EXPECT_TRUE(BN_add(y.get(), y.get(), p.get()));
+
+ EXPECT_FALSE(EC_POINT_set_affine_coordinates_GFp(group(), invalid_point.get(),
+ x.get(), y.get(), nullptr));
+ EXPECT_FALSE(
+ EC_KEY_set_public_key_affine_coordinates(key.get(), x.get(), y.get()));
+}
+
+TEST_P(ECCurveTest, IsOnCurve) {
+ bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(GetParam()));
+ ASSERT_TRUE(key);
+ ASSERT_TRUE(EC_KEY_generate_key(key.get()));
+
+ // The generated point is on the curve.
+ EXPECT_TRUE(EC_POINT_is_on_curve(group(), EC_KEY_get0_public_key(key.get()),
+ nullptr));
+
+ bssl::UniquePtr<EC_POINT> p(EC_POINT_new(group()));
+ ASSERT_TRUE(p);
+ ASSERT_TRUE(EC_POINT_copy(p.get(), EC_KEY_get0_public_key(key.get())));
+
+ // This should never happen outside of a bug, but |EC_POINT_is_on_curve|
+ // rejects points not on the curve.
+ OPENSSL_memset(&p->raw.X, 0, sizeof(p->raw.X));
+ EXPECT_FALSE(EC_POINT_is_on_curve(group(), p.get(), nullptr));
+
+ // The point at infinity is always on the curve.
+ ASSERT_TRUE(EC_POINT_copy(p.get(), EC_KEY_get0_public_key(key.get())));
+ OPENSSL_memset(&p->raw.Z, 0, sizeof(p->raw.Z));
+ EXPECT_TRUE(EC_POINT_is_on_curve(group(), p.get(), nullptr));
+}
+
+TEST_P(ECCurveTest, Compare) {
+ bssl::UniquePtr<EC_KEY> key1(EC_KEY_new_by_curve_name(GetParam()));
+ ASSERT_TRUE(key1);
+ ASSERT_TRUE(EC_KEY_generate_key(key1.get()));
+ const EC_POINT *pub1 = EC_KEY_get0_public_key(key1.get());
+
+ bssl::UniquePtr<EC_KEY> key2(EC_KEY_new_by_curve_name(GetParam()));
+ ASSERT_TRUE(key2);
+ ASSERT_TRUE(EC_KEY_generate_key(key2.get()));
+ const EC_POINT *pub2 = EC_KEY_get0_public_key(key2.get());
+
+ // Two different points should not compare as equal.
+ EXPECT_EQ(1, EC_POINT_cmp(group(), pub1, pub2, nullptr));
+
+ // Serialize |pub1| and parse it back out. This gives a point in affine
+ // coordinates.
+ std::vector<uint8_t> serialized;
+ ASSERT_TRUE(
+ EncodeECPoint(&serialized, group(), pub1, POINT_CONVERSION_UNCOMPRESSED));
+ bssl::UniquePtr<EC_POINT> p(EC_POINT_new(group()));
+ ASSERT_TRUE(p);
+ ASSERT_TRUE(EC_POINT_oct2point(group(), p.get(), serialized.data(),
+ serialized.size(), nullptr));
+
+ // The points should be equal.
+ EXPECT_EQ(0, EC_POINT_cmp(group(), p.get(), pub1, nullptr));
+
+ // Add something to the point. It no longer compares as equal.
+ ASSERT_TRUE(EC_POINT_add(group(), p.get(), p.get(), pub2, nullptr));
+ EXPECT_EQ(1, EC_POINT_cmp(group(), p.get(), pub1, nullptr));
+
+ // Negate |pub2|. It should no longer compare as equal. This tests that we
+ // check both x and y coordinate.
+ bssl::UniquePtr<EC_POINT> q(EC_POINT_new(group()));
+ ASSERT_TRUE(q);
+ ASSERT_TRUE(EC_POINT_copy(q.get(), pub2));
+ ASSERT_TRUE(EC_POINT_invert(group(), q.get(), nullptr));
+ EXPECT_EQ(1, EC_POINT_cmp(group(), q.get(), pub2, nullptr));
+
+ // Return |p| to the original value. It should be equal to |pub1| again.
+ ASSERT_TRUE(EC_POINT_add(group(), p.get(), p.get(), q.get(), nullptr));
+ EXPECT_EQ(0, EC_POINT_cmp(group(), p.get(), pub1, nullptr));
+
+ // Infinity compares as equal to itself, but not other points.
+ bssl::UniquePtr<EC_POINT> inf1(EC_POINT_new(group())),
+ inf2(EC_POINT_new(group()));
+ ASSERT_TRUE(inf1);
+ ASSERT_TRUE(inf2);
+ ASSERT_TRUE(EC_POINT_set_to_infinity(group(), inf1.get()));
+ // |q| is currently -|pub2|.
+ ASSERT_TRUE(EC_POINT_add(group(), inf2.get(), pub2, q.get(), nullptr));
+ EXPECT_EQ(0, EC_POINT_cmp(group(), inf1.get(), inf2.get(), nullptr));
+ EXPECT_EQ(1, EC_POINT_cmp(group(), inf1.get(), p.get(), nullptr));
+}
+
+TEST_P(ECCurveTest, GenerateFIPS) {
+ // Generate an EC_KEY.
+ bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(GetParam()));
+ ASSERT_TRUE(key);
+ ASSERT_TRUE(EC_KEY_generate_key_fips(key.get()));
+}
+
+TEST_P(ECCurveTest, AddingEqualPoints) {
+ bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(GetParam()));
+ ASSERT_TRUE(key);
+ ASSERT_TRUE(EC_KEY_generate_key(key.get()));
+
+ bssl::UniquePtr<EC_POINT> p1(EC_POINT_new(group()));
+ ASSERT_TRUE(p1);
+ ASSERT_TRUE(EC_POINT_copy(p1.get(), EC_KEY_get0_public_key(key.get())));
+
+ bssl::UniquePtr<EC_POINT> p2(EC_POINT_new(group()));
+ ASSERT_TRUE(p2);
+ ASSERT_TRUE(EC_POINT_copy(p2.get(), EC_KEY_get0_public_key(key.get())));
+
+ bssl::UniquePtr<EC_POINT> double_p1(EC_POINT_new(group()));
+ ASSERT_TRUE(double_p1);
+ bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());
+ ASSERT_TRUE(ctx);
+ ASSERT_TRUE(EC_POINT_dbl(group(), double_p1.get(), p1.get(), ctx.get()));
+
+ bssl::UniquePtr<EC_POINT> p1_plus_p2(EC_POINT_new(group()));
+ ASSERT_TRUE(p1_plus_p2);
+ ASSERT_TRUE(
+ EC_POINT_add(group(), p1_plus_p2.get(), p1.get(), p2.get(), ctx.get()));
+
+ EXPECT_EQ(0,
+ EC_POINT_cmp(group(), double_p1.get(), p1_plus_p2.get(), ctx.get()))
+ << "A+A != 2A";
+}
+
+TEST_P(ECCurveTest, MulZero) {
+ bssl::UniquePtr<EC_POINT> point(EC_POINT_new(group()));
+ ASSERT_TRUE(point);
+ bssl::UniquePtr<BIGNUM> zero(BN_new());
+ ASSERT_TRUE(zero);
+ BN_zero(zero.get());
+ ASSERT_TRUE(EC_POINT_mul(group(), point.get(), zero.get(), nullptr, nullptr,
+ nullptr));
+
+ EXPECT_TRUE(EC_POINT_is_at_infinity(group(), point.get()))
+ << "g * 0 did not return point at infinity.";
+
+ // Test that zero times an arbitrary point is also infinity. The generator is
+ // used as the arbitrary point.
+ bssl::UniquePtr<EC_POINT> generator(EC_POINT_new(group()));
+ ASSERT_TRUE(generator);
+ ASSERT_TRUE(EC_POINT_mul(group(), generator.get(), BN_value_one(), nullptr,
+ nullptr, nullptr));
+ ASSERT_TRUE(EC_POINT_mul(group(), point.get(), nullptr, generator.get(),
+ zero.get(), nullptr));
+
+ EXPECT_TRUE(EC_POINT_is_at_infinity(group(), point.get()))
+ << "p * 0 did not return point at infinity.";
+}
+
+// Test that multiplying by the order produces ∞ and, moreover, that callers may
+// do so. |EC_POINT_mul| is almost exclusively used with reduced scalars, with
+// this exception. This comes from consumers following NIST SP 800-56A section
+// 5.6.2.3.2. (Though all our curves have cofactor one, so this check isn't
+// useful.)
+TEST_P(ECCurveTest, MulOrder) {
+ // Test that g × order = ∞.
+ bssl::UniquePtr<EC_POINT> point(EC_POINT_new(group()));
+ ASSERT_TRUE(point);
+ ASSERT_TRUE(EC_POINT_mul(group(), point.get(), EC_GROUP_get0_order(group()),
+ nullptr, nullptr, nullptr));
+
+ EXPECT_TRUE(EC_POINT_is_at_infinity(group(), point.get()))
+ << "g * order did not return point at infinity.";
+
+ // Test that p × order = ∞, for some arbitrary p.
+ bssl::UniquePtr<BIGNUM> forty_two(BN_new());
+ ASSERT_TRUE(forty_two);
+ ASSERT_TRUE(BN_set_word(forty_two.get(), 42));
+ ASSERT_TRUE(EC_POINT_mul(group(), point.get(), forty_two.get(), nullptr,
+ nullptr, nullptr));
+ ASSERT_TRUE(EC_POINT_mul(group(), point.get(), nullptr, point.get(),
+ EC_GROUP_get0_order(group()), nullptr));
+
+ EXPECT_TRUE(EC_POINT_is_at_infinity(group(), point.get()))
+ << "p * order did not return point at infinity.";
+}
+
+// Test that |EC_POINT_mul| works with out-of-range scalars. The operation will
+// not be constant-time, but we'll compute the right answer.
+TEST_P(ECCurveTest, MulOutOfRange) {
+ bssl::UniquePtr<BIGNUM> n_minus_one(BN_dup(EC_GROUP_get0_order(group())));
+ ASSERT_TRUE(n_minus_one);
+ ASSERT_TRUE(BN_sub_word(n_minus_one.get(), 1));
+
+ bssl::UniquePtr<BIGNUM> minus_one(BN_new());
+ ASSERT_TRUE(minus_one);
+ ASSERT_TRUE(BN_one(minus_one.get()));
+ BN_set_negative(minus_one.get(), 1);
+
+ bssl::UniquePtr<BIGNUM> seven(BN_new());
+ ASSERT_TRUE(seven);
+ ASSERT_TRUE(BN_set_word(seven.get(), 7));
+
+ bssl::UniquePtr<BIGNUM> ten_n_plus_seven(
+ BN_dup(EC_GROUP_get0_order(group())));
+ ASSERT_TRUE(ten_n_plus_seven);
+ ASSERT_TRUE(BN_mul_word(ten_n_plus_seven.get(), 10));
+ ASSERT_TRUE(BN_add_word(ten_n_plus_seven.get(), 7));
+
+ bssl::UniquePtr<EC_POINT> point1(EC_POINT_new(group())),
+ point2(EC_POINT_new(group()));
+ ASSERT_TRUE(point1);
+ ASSERT_TRUE(point2);
+
+ ASSERT_TRUE(EC_POINT_mul(group(), point1.get(), n_minus_one.get(), nullptr,
+ nullptr, nullptr));
+ ASSERT_TRUE(EC_POINT_mul(group(), point2.get(), minus_one.get(), nullptr,
+ nullptr, nullptr));
+ EXPECT_EQ(0, EC_POINT_cmp(group(), point1.get(), point2.get(), nullptr))
+ << "-1 * G and (n-1) * G did not give the same result";
+
+ ASSERT_TRUE(EC_POINT_mul(group(), point1.get(), seven.get(), nullptr, nullptr,
+ nullptr));
+ ASSERT_TRUE(EC_POINT_mul(group(), point2.get(), ten_n_plus_seven.get(),
+ nullptr, nullptr, nullptr));
+ EXPECT_EQ(0, EC_POINT_cmp(group(), point1.get(), point2.get(), nullptr))
+ << "7 * G and (10n + 7) * G did not give the same result";
+}
+
+// Test that 10×∞ + G = G.
+TEST_P(ECCurveTest, Mul) {
+ bssl::UniquePtr<EC_POINT> p(EC_POINT_new(group()));
+ ASSERT_TRUE(p);
+ bssl::UniquePtr<EC_POINT> result(EC_POINT_new(group()));
+ ASSERT_TRUE(result);
+ bssl::UniquePtr<BIGNUM> n(BN_new());
+ ASSERT_TRUE(n);
+ ASSERT_TRUE(EC_POINT_set_to_infinity(group(), p.get()));
+ ASSERT_TRUE(BN_set_word(n.get(), 10));
+
+ // First check that 10×∞ = ∞.
+ ASSERT_TRUE(
+ EC_POINT_mul(group(), result.get(), nullptr, p.get(), n.get(), nullptr));
+ EXPECT_TRUE(EC_POINT_is_at_infinity(group(), result.get()));
+
+ // Now check that 10×∞ + G = G.
+ const EC_POINT *generator = EC_GROUP_get0_generator(group());
+ ASSERT_TRUE(EC_POINT_mul(group(), result.get(), BN_value_one(), p.get(),
+ n.get(), nullptr));
+ EXPECT_EQ(0, EC_POINT_cmp(group(), result.get(), generator, nullptr));
+}
+
+TEST_P(ECCurveTest, MulNonMinimal) {
+ bssl::UniquePtr<BIGNUM> forty_two(BN_new());
+ ASSERT_TRUE(forty_two);
+ ASSERT_TRUE(BN_set_word(forty_two.get(), 42));
+
+ // Compute g × 42.
+ bssl::UniquePtr<EC_POINT> point(EC_POINT_new(group()));
+ ASSERT_TRUE(point);
+ ASSERT_TRUE(EC_POINT_mul(group(), point.get(), forty_two.get(), nullptr,
+ nullptr, nullptr));
+
+ // Compute it again with a non-minimal 42, much larger than the scalar.
+ ASSERT_TRUE(bn_resize_words(forty_two.get(), 64));
+
+ bssl::UniquePtr<EC_POINT> point2(EC_POINT_new(group()));
+ ASSERT_TRUE(point2);
+ ASSERT_TRUE(EC_POINT_mul(group(), point2.get(), forty_two.get(), nullptr,
+ nullptr, nullptr));
+ EXPECT_EQ(0, EC_POINT_cmp(group(), point.get(), point2.get(), nullptr));
+}
+
+// Test that EC_KEY_set_private_key rejects invalid values.
+TEST_P(ECCurveTest, SetInvalidPrivateKey) {
+ bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(GetParam()));
+ ASSERT_TRUE(key);
+
+ bssl::UniquePtr<BIGNUM> bn(BN_dup(BN_value_one()));
+ ASSERT_TRUE(bn);
+ BN_set_negative(bn.get(), 1);
+ EXPECT_FALSE(EC_KEY_set_private_key(key.get(), bn.get()))
+ << "Unexpectedly set a key of -1";
+ ERR_clear_error();
+
+ ASSERT_TRUE(
+ BN_copy(bn.get(), EC_GROUP_get0_order(EC_KEY_get0_group(key.get()))));
+ EXPECT_FALSE(EC_KEY_set_private_key(key.get(), bn.get()))
+ << "Unexpectedly set a key of the group order.";
+ ERR_clear_error();
+
+ BN_zero(bn.get());
+ EXPECT_FALSE(EC_KEY_set_private_key(key.get(), bn.get()))
+ << "Unexpectedly set a key of 0";
+ ERR_clear_error();
+}
+
+TEST_P(ECCurveTest, IgnoreOct2PointReturnValue) {
+ bssl::UniquePtr<BIGNUM> forty_two(BN_new());
+ ASSERT_TRUE(forty_two);
+ ASSERT_TRUE(BN_set_word(forty_two.get(), 42));
+
+ // Compute g × 42.
+ bssl::UniquePtr<EC_POINT> point(EC_POINT_new(group()));
+ ASSERT_TRUE(point);
+ ASSERT_TRUE(EC_POINT_mul(group(), point.get(), forty_two.get(), nullptr,
+ nullptr, nullptr));
+
+ // Serialize the point.
+ std::vector<uint8_t> serialized;
+ ASSERT_TRUE(EncodeECPoint(&serialized, group(), point.get(),
+ POINT_CONVERSION_UNCOMPRESSED));
+
+ // Create a serialized point that is not on the curve.
+ serialized[serialized.size() - 1]++;
+
+ ASSERT_FALSE(EC_POINT_oct2point(group(), point.get(), serialized.data(),
+ serialized.size(), nullptr));
+ // After a failure, |point| should have been set to the generator to defend
+ // against code that doesn't check the return value.
+ ASSERT_EQ(0, EC_POINT_cmp(group(), point.get(),
+ EC_GROUP_get0_generator(group()), nullptr));
+}
+
+TEST_P(ECCurveTest, DoubleSpecialCase) {
+ const EC_POINT *g = EC_GROUP_get0_generator(group());
+
+ bssl::UniquePtr<EC_POINT> two_g(EC_POINT_new(group()));
+ ASSERT_TRUE(two_g);
+ ASSERT_TRUE(EC_POINT_dbl(group(), two_g.get(), g, nullptr));
+
+ bssl::UniquePtr<EC_POINT> p(EC_POINT_new(group()));
+ ASSERT_TRUE(p);
+ ASSERT_TRUE(EC_POINT_mul(group(), p.get(), BN_value_one(), g, BN_value_one(),
+ nullptr));
+ EXPECT_EQ(0, EC_POINT_cmp(group(), p.get(), two_g.get(), nullptr));
+
+ EC_SCALAR one;
+ ASSERT_TRUE(ec_bignum_to_scalar(group(), &one, BN_value_one()));
+ ASSERT_TRUE(
+ ec_point_mul_scalar_public(group(), &p->raw, &one, &g->raw, &one));
+ EXPECT_EQ(0, EC_POINT_cmp(group(), p.get(), two_g.get(), nullptr));
+}
+
+// This a regression test for a P-224 bug, but we may as well run it for all
+// curves.
+TEST_P(ECCurveTest, P224Bug) {
+ // P = -G
+ const EC_POINT *g = EC_GROUP_get0_generator(group());
+ bssl::UniquePtr<EC_POINT> p(EC_POINT_dup(g, group()));
+ ASSERT_TRUE(p);
+ ASSERT_TRUE(EC_POINT_invert(group(), p.get(), nullptr));
+
+ // Compute 31 * P + 32 * G = G
+ bssl::UniquePtr<EC_POINT> ret(EC_POINT_new(group()));
+ ASSERT_TRUE(ret);
+ bssl::UniquePtr<BIGNUM> bn31(BN_new()), bn32(BN_new());
+ ASSERT_TRUE(bn31);
+ ASSERT_TRUE(bn32);
+ ASSERT_TRUE(BN_set_word(bn31.get(), 31));
+ ASSERT_TRUE(BN_set_word(bn32.get(), 32));
+ ASSERT_TRUE(EC_POINT_mul(group(), ret.get(), bn32.get(), p.get(), bn31.get(),
+ nullptr));
+ EXPECT_EQ(0, EC_POINT_cmp(group(), ret.get(), g, nullptr));
+
+ // Repeat the computation with |ec_point_mul_scalar_public|, which ties the
+ // additions together.
+ EC_SCALAR sc31, sc32;
+ ASSERT_TRUE(ec_bignum_to_scalar(group(), &sc31, bn31.get()));
+ ASSERT_TRUE(ec_bignum_to_scalar(group(), &sc32, bn32.get()));
+ ASSERT_TRUE(
+ ec_point_mul_scalar_public(group(), &ret->raw, &sc32, &p->raw, &sc31));
+ EXPECT_EQ(0, EC_POINT_cmp(group(), ret.get(), g, nullptr));
+}
+
+TEST_P(ECCurveTest, GPlusMinusG) {
+ const EC_POINT *g = EC_GROUP_get0_generator(group());
+
+ bssl::UniquePtr<EC_POINT> p(EC_POINT_dup(g, group()));
+ ASSERT_TRUE(p);
+ ASSERT_TRUE(EC_POINT_invert(group(), p.get(), nullptr));
+
+ bssl::UniquePtr<EC_POINT> sum(EC_POINT_new(group()));
+ ASSERT_TRUE(sum);
+ ASSERT_TRUE(EC_POINT_add(group(), sum.get(), g, p.get(), nullptr));
+ EXPECT_TRUE(EC_POINT_is_at_infinity(group(), sum.get()));
+}
+
+// Test that we refuse to encode or decode the point at infinity.
+TEST_P(ECCurveTest, EncodeInfinity) {
+ // The point at infinity is encoded as a single zero byte, but we do not
+ // support it.
+ static const uint8_t kInfinity[] = {0};
+ bssl::UniquePtr<EC_POINT> inf(EC_POINT_new(group()));
+ ASSERT_TRUE(inf);
+ EXPECT_FALSE(EC_POINT_oct2point(group(), inf.get(), kInfinity,
+ sizeof(kInfinity), nullptr));
+
+ // Encoding it also fails.
+ ASSERT_TRUE(EC_POINT_set_to_infinity(group(), inf.get()));
+ uint8_t buf[128];
+ EXPECT_EQ(
+ 0u, EC_POINT_point2oct(group(), inf.get(), POINT_CONVERSION_UNCOMPRESSED,
+ buf, sizeof(buf), nullptr));
+
+ // Measuring the length of the encoding also fails.
+ EXPECT_EQ(
+ 0u, EC_POINT_point2oct(group(), inf.get(), POINT_CONVERSION_UNCOMPRESSED,
+ nullptr, 0, nullptr));
+}
+
+static std::vector<int> AllCurves() {
+ const size_t num_curves = EC_get_builtin_curves(nullptr, 0);
+ std::vector<EC_builtin_curve> curves(num_curves);
+ EC_get_builtin_curves(curves.data(), num_curves);
+ std::vector<int> nids;
+ for (const auto& curve : curves) {
+ nids.push_back(curve.nid);
+ }
+ return nids;
+}
+
+static std::string CurveToString(const testing::TestParamInfo<int> &params) {
+ return OBJ_nid2sn(params.param);
+}
+
+INSTANTIATE_TEST_SUITE_P(All, ECCurveTest, testing::ValuesIn(AllCurves()),
+ CurveToString);
+
+static bssl::UniquePtr<EC_GROUP> GetCurve(FileTest *t, const char *key) {
+ std::string curve_name;
+ if (!t->GetAttribute(&curve_name, key)) {
+ return nullptr;
+ }
+
+ if (curve_name == "P-224") {
+ return bssl::UniquePtr<EC_GROUP>(EC_GROUP_new_by_curve_name(NID_secp224r1));
+ }
+ if (curve_name == "P-256") {
+ return bssl::UniquePtr<EC_GROUP>(EC_GROUP_new_by_curve_name(
+ NID_X9_62_prime256v1));
+ }
+ if (curve_name == "P-384") {
+ return bssl::UniquePtr<EC_GROUP>(EC_GROUP_new_by_curve_name(NID_secp384r1));
+ }
+ if (curve_name == "P-521") {
+ return bssl::UniquePtr<EC_GROUP>(EC_GROUP_new_by_curve_name(NID_secp521r1));
+ }
+
+ t->PrintLine("Unknown curve '%s'", curve_name.c_str());
+ return nullptr;
+}
+
+static bssl::UniquePtr<BIGNUM> GetBIGNUM(FileTest *t, const char *key) {
+ std::vector<uint8_t> bytes;
+ if (!t->GetBytes(&bytes, key)) {
+ return nullptr;
+ }
+
+ return bssl::UniquePtr<BIGNUM>(
+ BN_bin2bn(bytes.data(), bytes.size(), nullptr));
+}
+
+TEST(ECTest, ScalarBaseMultVectors) {
+ bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());
+ ASSERT_TRUE(ctx);
+
+ FileTestGTest("crypto/fipsmodule/ec/ec_scalar_base_mult_tests.txt",
+ [&](FileTest *t) {
+ bssl::UniquePtr<EC_GROUP> group = GetCurve(t, "Curve");
+ ASSERT_TRUE(group);
+ bssl::UniquePtr<BIGNUM> n = GetBIGNUM(t, "N");
+ ASSERT_TRUE(n);
+ bssl::UniquePtr<BIGNUM> x = GetBIGNUM(t, "X");
+ ASSERT_TRUE(x);
+ bssl::UniquePtr<BIGNUM> y = GetBIGNUM(t, "Y");
+ ASSERT_TRUE(y);
+ bool is_infinity = BN_is_zero(x.get()) && BN_is_zero(y.get());
+
+ bssl::UniquePtr<BIGNUM> px(BN_new());
+ ASSERT_TRUE(px);
+ bssl::UniquePtr<BIGNUM> py(BN_new());
+ ASSERT_TRUE(py);
+ auto check_point = [&](const EC_POINT *p) {
+ if (is_infinity) {
+ EXPECT_TRUE(EC_POINT_is_at_infinity(group.get(), p));
+ } else {
+ ASSERT_TRUE(EC_POINT_get_affine_coordinates_GFp(
+ group.get(), p, px.get(), py.get(), ctx.get()));
+ EXPECT_EQ(0, BN_cmp(x.get(), px.get()));
+ EXPECT_EQ(0, BN_cmp(y.get(), py.get()));
+ }
+ };
+
+ const EC_POINT *g = EC_GROUP_get0_generator(group.get());
+ bssl::UniquePtr<EC_POINT> p(EC_POINT_new(group.get()));
+ ASSERT_TRUE(p);
+ // Test single-point multiplication.
+ ASSERT_TRUE(EC_POINT_mul(group.get(), p.get(), n.get(), nullptr, nullptr,
+ ctx.get()));
+ check_point(p.get());
+
+ ASSERT_TRUE(
+ EC_POINT_mul(group.get(), p.get(), nullptr, g, n.get(), ctx.get()));
+ check_point(p.get());
+ });
+}
+
+// These tests take a very long time, but are worth running when we make
+// non-trivial changes to the EC code.
+TEST(ECTest, DISABLED_ScalarBaseMultVectorsTwoPoint) {
+ bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());
+ ASSERT_TRUE(ctx);
+
+ FileTestGTest("crypto/fipsmodule/ec/ec_scalar_base_mult_tests.txt",
+ [&](FileTest *t) {
+ bssl::UniquePtr<EC_GROUP> group = GetCurve(t, "Curve");
+ ASSERT_TRUE(group);
+ bssl::UniquePtr<BIGNUM> n = GetBIGNUM(t, "N");
+ ASSERT_TRUE(n);
+ bssl::UniquePtr<BIGNUM> x = GetBIGNUM(t, "X");
+ ASSERT_TRUE(x);
+ bssl::UniquePtr<BIGNUM> y = GetBIGNUM(t, "Y");
+ ASSERT_TRUE(y);
+ bool is_infinity = BN_is_zero(x.get()) && BN_is_zero(y.get());
+
+ bssl::UniquePtr<BIGNUM> px(BN_new());
+ ASSERT_TRUE(px);
+ bssl::UniquePtr<BIGNUM> py(BN_new());
+ ASSERT_TRUE(py);
+ auto check_point = [&](const EC_POINT *p) {
+ if (is_infinity) {
+ EXPECT_TRUE(EC_POINT_is_at_infinity(group.get(), p));
+ } else {
+ ASSERT_TRUE(EC_POINT_get_affine_coordinates_GFp(
+ group.get(), p, px.get(), py.get(), ctx.get()));
+ EXPECT_EQ(0, BN_cmp(x.get(), px.get()));
+ EXPECT_EQ(0, BN_cmp(y.get(), py.get()));
+ }
+ };
+
+ const EC_POINT *g = EC_GROUP_get0_generator(group.get());
+ bssl::UniquePtr<EC_POINT> p(EC_POINT_new(group.get()));
+ ASSERT_TRUE(p);
+ bssl::UniquePtr<BIGNUM> a(BN_new()), b(BN_new());
+ for (int i = -64; i < 64; i++) {
+ SCOPED_TRACE(i);
+ ASSERT_TRUE(BN_set_word(a.get(), abs(i)));
+ if (i < 0) {
+ ASSERT_TRUE(BN_sub(a.get(), EC_GROUP_get0_order(group.get()), a.get()));
+ }
+
+ ASSERT_TRUE(BN_copy(b.get(), n.get()));
+ ASSERT_TRUE(BN_sub(b.get(), b.get(), a.get()));
+ if (BN_is_negative(b.get())) {
+ ASSERT_TRUE(BN_add(b.get(), b.get(), EC_GROUP_get0_order(group.get())));
+ }
+
+ ASSERT_TRUE(
+ EC_POINT_mul(group.get(), p.get(), a.get(), g, b.get(), ctx.get()));
+ check_point(p.get());
+
+ EC_SCALAR a_scalar, b_scalar;
+ ASSERT_TRUE(ec_bignum_to_scalar(group.get(), &a_scalar, a.get()));
+ ASSERT_TRUE(ec_bignum_to_scalar(group.get(), &b_scalar, b.get()));
+ ASSERT_TRUE(ec_point_mul_scalar_public(group.get(), &p->raw, &a_scalar,
+ &g->raw, &b_scalar));
+ check_point(p.get());
+ }
+ });
+}
+
+static std::vector<uint8_t> HexToBytes(const char *str) {
+ std::vector<uint8_t> ret;
+ if (!DecodeHex(&ret, str)) {
+ abort();
+ }
+ return ret;
+}
+
+TEST(ECTest, DeriveFromSecret) {
+ struct DeriveTest {
+ int curve;
+ std::vector<uint8_t> secret;
+ std::vector<uint8_t> expected_priv;
+ std::vector<uint8_t> expected_pub;
+ };
+ const DeriveTest kDeriveTests[] = {
+ {NID_X9_62_prime256v1, HexToBytes(""),
+ HexToBytes(
+ "b98a86a71efb51ebdac4759937b977e9b0c05224675bb2b6a58ba306e237f4b8"),
+ HexToBytes(
+ "04fbe6cab439918e00231a2ff073cdc25823998864a9eb36f809095a1a919ece875"
+ "a145803fbe89a6cde53936e3c6d9c253ed3d38f5f58cae455c27e95645ceda9")},
+ {NID_X9_62_prime256v1, HexToBytes("123456"),
+ HexToBytes(
+ "44a72bc62087b88e5ab7126766177ed0d8f1ed09ad066cd746527fc201105a7e"),
+ HexToBytes(
+ "04ec0555cd76e991fef7f5504343937d0f38696db3360a4854052cb0d84a377a5a0"
+ "ff64c352755c28692b4ae085c2b817db9a1eddbd22e9cf39c12751e0870791b")},
+ {NID_X9_62_prime256v1, HexToBytes("00000000000000000000000000000000"),
+ HexToBytes(
+ "7ca1e2c83e6a5f2c1b3e7d58180226f269930c4b9fbe2a275096079630b7c57d"),
+ HexToBytes(
+ "0442ef70c8fc0fbe383ed0a0da36f39f9a590f3feebc07863cc858c9a8ef0465731"
+ "0408c249bd4d61929c54b71ffe056e6b4fa1eb537039b43d1c175f0ceab0f89")},
+ {NID_X9_62_prime256v1,
+ HexToBytes(
+ "de9c9b35543aaa0fba039e34e8ca9695da3225c7161c9e3a8c70356cac28c780"),
+ HexToBytes(
+ "659f5abf3b62b9931c29d6ed0722efd2349fa56f54e708cf3272f620f1bc44d0"),
+ HexToBytes(
+ "046741f806b593bf3a3d4a9d76bdcb9b0d7874633cbea8f42c05e78561f7e8ec362"
+ "b9b6f1913ded796fbdafe7f210cea897ac22a4e580c06a60f2659fd09f1830f")},
+ {NID_secp384r1, HexToBytes("123456"),
+ HexToBytes("95cd90d548997de090c7622708eccb7edc1b1bd78d2422235ad97406dada"
+ "076555309da200096f6e4b36c46002beee89"),
+ HexToBytes(
+ "04007b2d026aa7636fa912c3f970d62bb6c10fa81c8f3290ed90b2d701696d1c6b9"
+ "5af88ce13e962996a7ac37e16527cb5d69bd081b8641d07634cf84b438600ec9434"
+ "15ac6bd7a0236f7ab0ea31ece67df03fa11646ea2b75e73d1b5e45b75c18")},
+ };
+
+ for (const auto &test : kDeriveTests) {
+ SCOPED_TRACE(Bytes(test.secret));
+ bssl::UniquePtr<EC_GROUP> group(EC_GROUP_new_by_curve_name(test.curve));
+ ASSERT_TRUE(group);
+ bssl::UniquePtr<EC_KEY> key(EC_KEY_derive_from_secret(
+ group.get(), test.secret.data(), test.secret.size()));
+ ASSERT_TRUE(key);
+
+ std::vector<uint8_t> priv(BN_num_bytes(EC_GROUP_get0_order(group.get())));
+ ASSERT_TRUE(BN_bn2bin_padded(priv.data(), priv.size(),
+ EC_KEY_get0_private_key(key.get())));
+ EXPECT_EQ(Bytes(priv), Bytes(test.expected_priv));
+
+ uint8_t *pub = nullptr;
+ size_t pub_len =
+ EC_KEY_key2buf(key.get(), POINT_CONVERSION_UNCOMPRESSED, &pub, nullptr);
+ bssl::UniquePtr<uint8_t> free_pub(pub);
+ EXPECT_NE(pub_len, 0u);
+ EXPECT_EQ(Bytes(pub, pub_len), Bytes(test.expected_pub));
+ }
+}
+
+TEST(ECTest, HashToCurve) {
+ auto hash_to_curve_p384_sha512_draft07 =
+ [](const EC_GROUP *group, EC_POINT *out, const uint8_t *dst,
+ size_t dst_len, const uint8_t *msg, size_t msg_len) -> int {
+ if (EC_GROUP_cmp(group, out->group, NULL) != 0) {
+ return 0;
+ }
+ return ec_hash_to_curve_p384_xmd_sha512_sswu_draft07(group, &out->raw, dst,
+ dst_len, msg, msg_len);
+ };
+
+ struct HashToCurveTest {
+ int (*hash_to_curve)(const EC_GROUP *group, EC_POINT *out,
+ const uint8_t *dst, size_t dst_len, const uint8_t *msg,
+ size_t msg_len);
+ int curve_nid;
+ const char *dst;
+ const char *msg;
+ const char *x_hex;
+ const char *y_hex;
+ };
+ static const HashToCurveTest kTests[] = {
+ // See draft-irtf-cfrg-hash-to-curve-16, appendix J.1.1.
+ {&EC_hash_to_curve_p256_xmd_sha256_sswu, NID_X9_62_prime256v1,
+ "QUUX-V01-CS02-with-P256_XMD:SHA-256_SSWU_RO_", "",
+ "2c15230b26dbc6fc9a37051158c95b79656e17a1a920b11394ca91"
+ "c44247d3e4",
+ "8a7a74985cc5c776cdfe4b1f19884970453912e9d31528c060be9a"
+ "b5c43e8415"},
+ {&EC_hash_to_curve_p256_xmd_sha256_sswu, NID_X9_62_prime256v1,
+ "QUUX-V01-CS02-with-P256_XMD:SHA-256_SSWU_RO_", "abc",
+ "0bb8b87485551aa43ed54f009230450b492fead5f1cc91658775da"
+ "c4a3388a0f",
+ "5c41b3d0731a27a7b14bc0bf0ccded2d8751f83493404c84a88e71"
+ "ffd424212e"},
+ {&EC_hash_to_curve_p256_xmd_sha256_sswu, NID_X9_62_prime256v1,
+ "QUUX-V01-CS02-with-P256_XMD:SHA-256_SSWU_RO_", "abcdef0123456789",
+ "65038ac8f2b1def042a5df0b33b1f4eca6bff7cb0f9c6c15268118"
+ "64e544ed80",
+ "cad44d40a656e7aff4002a8de287abc8ae0482b5ae825822bb870d"
+ "6df9b56ca3"},
+ {&EC_hash_to_curve_p256_xmd_sha256_sswu, NID_X9_62_prime256v1,
+ "QUUX-V01-CS02-with-P256_XMD:SHA-256_SSWU_RO_",
+ "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq"
+ "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq"
+ "qqqqqqqqqqqqqqqqqqqqqqqqq",
+ "4be61ee205094282ba8a2042bcb48d88dfbb609301c49aa8b07853"
+ "3dc65a0b5d",
+ "98f8df449a072c4721d241a3b1236d3caccba603f916ca680f4539"
+ "d2bfb3c29e"},
+ {&EC_hash_to_curve_p256_xmd_sha256_sswu, NID_X9_62_prime256v1,
+ "QUUX-V01-CS02-with-P256_XMD:SHA-256_SSWU_RO_",
+ "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ "457ae2981f70ca85d8e24c308b14db22f3e3862c5ea0f652ca38b5"
+ "e49cd64bc5",
+ "ecb9f0eadc9aeed232dabc53235368c1394c78de05dd96893eefa6"
+ "2b0f4757dc"},
+
+ // See draft-irtf-cfrg-hash-to-curve-07, appendix G.2.1.
+ {hash_to_curve_p384_sha512_draft07, NID_secp384r1,
+ "P384_XMD:SHA-512_SSWU_RO_TESTGEN", "",
+ "2fc0b9efdd63a8e43b4db88dc12f03c798f6fd91bccac0c9096185"
+ "4386e58fdc54fc2a01f0f358759054ce1f9b762025",
+ "949b936fabb72cdb02cd7980b86cb6a3adf286658e81301648851d"
+ "b8a49d9bec00ccb57698d559fc5960fa5030a8e54b"},
+ {hash_to_curve_p384_sha512_draft07, NID_secp384r1,
+ "P384_XMD:SHA-512_SSWU_RO_TESTGEN", "abc",
+ "4f3338035391e8ce8ce40c974136f0edc97f392ffd44a643338741"
+ "8ed1b8c2603487e1688ec151f048fbc6b2c138c92f",
+ "152b90aef6558be328a3168855fb1906452e7167b0f7c8a56ff9d4"
+ "fa87d6fb522cdf8e409db54418b2c764fd26260757"},
+ {hash_to_curve_p384_sha512_draft07, NID_secp384r1,
+ "P384_XMD:SHA-512_SSWU_RO_TESTGEN", "abcdef0123456789",
+ "e9e5d7ac397e123d060ad44301cbc8eb972f6e64ebcff29dcc9b9a"
+ "10357902aace2240c580fec85e5b427d98b4e80703",
+ "916cb8963521ad75105be43cc4148e5a5bbb4fcf107f1577e4f7fa"
+ "3ca58cd786aa76890c8e687d2353393bc16c78ec4d"},
+ {hash_to_curve_p384_sha512_draft07, NID_secp384r1,
+ "P384_XMD:SHA-512_SSWU_RO_TESTGEN",
+ "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ "41941db59a7b8b633bd5bfa462f1e29a9f18e5a341445d90fc6eb9"
+ "37f2913224287b9dfb64742851f760eb14ca115ff9",
+ "1510e764f1be968d661b7aaecb26a6d38c98e5205ca150f0ae426d"
+ "2c3983c68e3a9ffb283c6ae4891d891b5705500475"},
+ };
+
+ for (const auto &test : kTests) {
+ SCOPED_TRACE(test.dst);
+ SCOPED_TRACE(test.msg);
+
+ bssl::UniquePtr<EC_GROUP> group(EC_GROUP_new_by_curve_name(test.curve_nid));
+ ASSERT_TRUE(group);
+ bssl::UniquePtr<EC_POINT> p(EC_POINT_new(group.get()));
+ ASSERT_TRUE(p);
+ ASSERT_TRUE(test.hash_to_curve(
+ group.get(), p.get(), reinterpret_cast<const uint8_t *>(test.dst),
+ strlen(test.dst), reinterpret_cast<const uint8_t *>(test.msg),
+ strlen(test.msg)));
+
+ std::vector<uint8_t> buf;
+ ASSERT_TRUE(EncodeECPoint(&buf, group.get(), p.get(),
+ POINT_CONVERSION_UNCOMPRESSED));
+ size_t field_len = (buf.size() - 1) / 2;
+ EXPECT_EQ(test.x_hex,
+ EncodeHex(bssl::MakeConstSpan(buf).subspan(1, field_len)));
+ EXPECT_EQ(test.y_hex, EncodeHex(bssl::MakeConstSpan(buf).subspan(
+ 1 + field_len, field_len)));
+ }
+
+ // hash-to-curve functions should check for the wrong group.
+ bssl::UniquePtr<EC_GROUP> p224(EC_GROUP_new_by_curve_name(NID_secp224r1));
+ ASSERT_TRUE(p224);
+ bssl::UniquePtr<EC_GROUP> p384(EC_GROUP_new_by_curve_name(NID_secp384r1));
+ ASSERT_TRUE(p384);
+ EC_JACOBIAN raw;
+ bssl::UniquePtr<EC_POINT> p_p384(EC_POINT_new(p384.get()));
+ ASSERT_TRUE(p_p384);
+ bssl::UniquePtr<EC_POINT> p_p224(EC_POINT_new(p224.get()));
+ ASSERT_TRUE(p_p224);
+ static const uint8_t kDST[] = {0, 1, 2, 3};
+ static const uint8_t kMessage[] = {4, 5, 6, 7};
+ EXPECT_FALSE(ec_hash_to_curve_p384_xmd_sha384_sswu(
+ p224.get(), &raw, kDST, sizeof(kDST), kMessage, sizeof(kMessage)));
+ EXPECT_FALSE(EC_hash_to_curve_p384_xmd_sha384_sswu(
+ p224.get(), p_p224.get(), kDST, sizeof(kDST), kMessage,
+ sizeof(kMessage)));
+ EXPECT_FALSE(EC_hash_to_curve_p384_xmd_sha384_sswu(
+ p224.get(), p_p384.get(), kDST, sizeof(kDST), kMessage,
+ sizeof(kMessage)));
+ EXPECT_FALSE(EC_hash_to_curve_p384_xmd_sha384_sswu(
+ p384.get(), p_p224.get(), kDST, sizeof(kDST), kMessage,
+ sizeof(kMessage)));
+
+ // Zero-length DSTs are not allowed.
+ EXPECT_FALSE(ec_hash_to_curve_p384_xmd_sha384_sswu(
+ p384.get(), &raw, nullptr, 0, kMessage, sizeof(kMessage)));
+}
+
+TEST(ECTest, HashToScalar) {
+ struct HashToScalarTest {
+ int (*hash_to_scalar)(const EC_GROUP *group, EC_SCALAR *out,
+ const uint8_t *dst, size_t dst_len,
+ const uint8_t *msg, size_t msg_len);
+ int curve_nid;
+ const char *dst;
+ const char *msg;
+ const char *result_hex;
+ };
+ static const HashToScalarTest kTests[] = {
+ {&ec_hash_to_scalar_p384_xmd_sha512_draft07, NID_secp384r1,
+ "P384_XMD:SHA-512_SCALAR_TEST", "",
+ "9687acc2de56c3cf94c0e05b6811a21aa480092254ec0532bdce63"
+ "140ecd340f09dc2d45d77e21fb0aa76f7707b8a676"},
+ {&ec_hash_to_scalar_p384_xmd_sha512_draft07, NID_secp384r1,
+ "P384_XMD:SHA-512_SCALAR_TEST", "abcdef0123456789",
+ "8f8076022a68233cbcecaceae68c2068f132724f001caa78619eff"
+ "1ffc58fa871db73fe9034fc9cf853c384ed34b5666"},
+ {&ec_hash_to_scalar_p384_xmd_sha512_draft07, NID_secp384r1,
+ "P384_XMD:SHA-512_SCALAR_TEST",
+ "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ "750f2fae7d2b2f41ac737d180c1d4363d85a1504798b4976d40921"
+ "1ddb3651c13a5b4daba9975cdfce18336791131915"},
+ };
+
+ for (const auto &test : kTests) {
+ SCOPED_TRACE(test.dst);
+ SCOPED_TRACE(test.msg);
+
+ bssl::UniquePtr<EC_GROUP> group(EC_GROUP_new_by_curve_name(test.curve_nid));
+ ASSERT_TRUE(group);
+ EC_SCALAR scalar;
+ ASSERT_TRUE(test.hash_to_scalar(
+ group.get(), &scalar, reinterpret_cast<const uint8_t *>(test.dst),
+ strlen(test.dst), reinterpret_cast<const uint8_t *>(test.msg),
+ strlen(test.msg)));
+ uint8_t buf[EC_MAX_BYTES];
+ size_t len;
+ ec_scalar_to_bytes(group.get(), buf, &len, &scalar);
+ EXPECT_EQ(test.result_hex, EncodeHex(bssl::MakeConstSpan(buf, len)));
+ }
+
+ // hash-to-scalar functions should check for the wrong group.
+ bssl::UniquePtr<EC_GROUP> p224(EC_GROUP_new_by_curve_name(NID_secp224r1));
+ ASSERT_TRUE(p224);
+ EC_SCALAR scalar;
+ static const uint8_t kDST[] = {0, 1, 2, 3};
+ static const uint8_t kMessage[] = {4, 5, 6, 7};
+ EXPECT_FALSE(ec_hash_to_scalar_p384_xmd_sha512_draft07(
+ p224.get(), &scalar, kDST, sizeof(kDST), kMessage, sizeof(kMessage)));
+}
diff --git a/src/crypto/fipsmodule/ec/felem.c b/src/crypto/fipsmodule/ec/felem.c
new file mode 100644
index 0000000..e462514
--- /dev/null
+++ b/src/crypto/fipsmodule/ec/felem.c
@@ -0,0 +1,100 @@
+/* Copyright (c) 2018, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <openssl/ec.h>
+#include <openssl/err.h>
+#include <openssl/mem.h>
+
+#include <assert.h>
+
+#include "internal.h"
+#include "../bn/internal.h"
+#include "../../internal.h"
+
+
+int ec_bignum_to_felem(const EC_GROUP *group, EC_FELEM *out, const BIGNUM *in) {
+ uint8_t bytes[EC_MAX_BYTES];
+ size_t len = BN_num_bytes(&group->field);
+ assert(sizeof(bytes) >= len);
+ if (BN_is_negative(in) ||
+ BN_cmp(in, &group->field) >= 0 ||
+ !BN_bn2bin_padded(bytes, len, in)) {
+ OPENSSL_PUT_ERROR(EC, EC_R_COORDINATES_OUT_OF_RANGE);
+ return 0;
+ }
+
+ return ec_felem_from_bytes(group, out, bytes, len);
+}
+
+int ec_felem_to_bignum(const EC_GROUP *group, BIGNUM *out, const EC_FELEM *in) {
+ uint8_t bytes[EC_MAX_BYTES];
+ size_t len;
+ ec_felem_to_bytes(group, bytes, &len, in);
+ return BN_bin2bn(bytes, len, out) != NULL;
+}
+
+void ec_felem_to_bytes(const EC_GROUP *group, uint8_t *out, size_t *out_len,
+ const EC_FELEM *in) {
+ group->meth->felem_to_bytes(group, out, out_len, in);
+}
+
+int ec_felem_from_bytes(const EC_GROUP *group, EC_FELEM *out, const uint8_t *in,
+ size_t len) {
+ return group->meth->felem_from_bytes(group, out, in, len);
+}
+
+void ec_felem_neg(const EC_GROUP *group, EC_FELEM *out, const EC_FELEM *a) {
+ // -a is zero if a is zero and p-a otherwise.
+ BN_ULONG mask = ec_felem_non_zero_mask(group, a);
+ BN_ULONG borrow =
+ bn_sub_words(out->words, group->field.d, a->words, group->field.width);
+ assert(borrow == 0);
+ (void)borrow;
+ for (int i = 0; i < group->field.width; i++) {
+ out->words[i] &= mask;
+ }
+}
+
+void ec_felem_add(const EC_GROUP *group, EC_FELEM *out, const EC_FELEM *a,
+ const EC_FELEM *b) {
+ EC_FELEM tmp;
+ bn_mod_add_words(out->words, a->words, b->words, group->field.d, tmp.words,
+ group->field.width);
+}
+
+void ec_felem_sub(const EC_GROUP *group, EC_FELEM *out, const EC_FELEM *a,
+ const EC_FELEM *b) {
+ EC_FELEM tmp;
+ bn_mod_sub_words(out->words, a->words, b->words, group->field.d, tmp.words,
+ group->field.width);
+}
+
+BN_ULONG ec_felem_non_zero_mask(const EC_GROUP *group, const EC_FELEM *a) {
+ BN_ULONG mask = 0;
+ for (int i = 0; i < group->field.width; i++) {
+ mask |= a->words[i];
+ }
+ return ~constant_time_is_zero_w(mask);
+}
+
+void ec_felem_select(const EC_GROUP *group, EC_FELEM *out, BN_ULONG mask,
+ const EC_FELEM *a, const EC_FELEM *b) {
+ bn_select_words(out->words, mask, a->words, b->words, group->field.width);
+}
+
+int ec_felem_equal(const EC_GROUP *group, const EC_FELEM *a,
+ const EC_FELEM *b) {
+ return CRYPTO_memcmp(a->words, b->words,
+ group->field.width * sizeof(BN_ULONG)) == 0;
+}
diff --git a/src/crypto/fipsmodule/ec/internal.h b/src/crypto/fipsmodule/ec/internal.h
new file mode 100644
index 0000000..8532026
--- /dev/null
+++ b/src/crypto/fipsmodule/ec/internal.h
@@ -0,0 +1,794 @@
+/* Originally written by Bodo Moeller for the OpenSSL project.
+ * ====================================================================
+ * Copyright (c) 1998-2005 The OpenSSL Project. 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.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS 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.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * The elliptic curve binary polynomial software is originally written by
+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems
+ * Laboratories. */
+
+#ifndef OPENSSL_HEADER_EC_INTERNAL_H
+#define OPENSSL_HEADER_EC_INTERNAL_H
+
+#include <openssl/base.h>
+
+#include <assert.h>
+
+#include <openssl/bn.h>
+#include <openssl/ec.h>
+#include <openssl/ex_data.h>
+
+#include "../bn/internal.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+// EC internals.
+
+
+// Cap the size of all field elements and scalars, including custom curves, to
+// 66 bytes, large enough to fit secp521r1 and brainpoolP512r1, which appear to
+// be the largest fields anyone plausibly uses.
+#define EC_MAX_BYTES 66
+#define EC_MAX_WORDS ((EC_MAX_BYTES + BN_BYTES - 1) / BN_BYTES)
+#define EC_MAX_COMPRESSED (EC_MAX_BYTES + 1)
+#define EC_MAX_UNCOMPRESSED (2 * EC_MAX_BYTES + 1)
+
+static_assert(EC_MAX_WORDS <= BN_SMALL_MAX_WORDS,
+ "bn_*_small functions not usable");
+
+
+// Scalars.
+
+// An EC_SCALAR is an integer fully reduced modulo the order. Only the first
+// |order->width| words are used. An |EC_SCALAR| is specific to an |EC_GROUP|
+// and must not be mixed between groups.
+typedef struct {
+ BN_ULONG words[EC_MAX_WORDS];
+} EC_SCALAR;
+
+// ec_bignum_to_scalar converts |in| to an |EC_SCALAR| and writes it to
+// |*out|. It returns one on success and zero if |in| is out of range.
+OPENSSL_EXPORT int ec_bignum_to_scalar(const EC_GROUP *group, EC_SCALAR *out,
+ const BIGNUM *in);
+
+// ec_scalar_to_bytes serializes |in| as a big-endian bytestring to |out| and
+// sets |*out_len| to the number of bytes written. The number of bytes written
+// is |BN_num_bytes(&group->order)|, which is at most |EC_MAX_BYTES|.
+OPENSSL_EXPORT void ec_scalar_to_bytes(const EC_GROUP *group, uint8_t *out,
+ size_t *out_len, const EC_SCALAR *in);
+
+// ec_scalar_from_bytes deserializes |in| and stores the resulting scalar over
+// group |group| to |out|. It returns one on success and zero if |in| is
+// invalid.
+OPENSSL_EXPORT int ec_scalar_from_bytes(const EC_GROUP *group, EC_SCALAR *out,
+ const uint8_t *in, size_t len);
+
+// ec_scalar_reduce sets |out| to |words|, reduced modulo the group order.
+// |words| must be less than order^2. |num| must be at most twice the width of
+// group order. This function treats |words| as secret.
+void ec_scalar_reduce(const EC_GROUP *group, EC_SCALAR *out,
+ const BN_ULONG *words, size_t num);
+
+// ec_random_nonzero_scalar sets |out| to a uniformly selected random value from
+// 1 to |group->order| - 1. It returns one on success and zero on error.
+int ec_random_nonzero_scalar(const EC_GROUP *group, EC_SCALAR *out,
+ const uint8_t additional_data[32]);
+
+// ec_scalar_equal_vartime returns one if |a| and |b| are equal and zero
+// otherwise. Both values are treated as public.
+int ec_scalar_equal_vartime(const EC_GROUP *group, const EC_SCALAR *a,
+ const EC_SCALAR *b);
+
+// ec_scalar_is_zero returns one if |a| is zero and zero otherwise.
+int ec_scalar_is_zero(const EC_GROUP *group, const EC_SCALAR *a);
+
+// ec_scalar_add sets |r| to |a| + |b|.
+void ec_scalar_add(const EC_GROUP *group, EC_SCALAR *r, const EC_SCALAR *a,
+ const EC_SCALAR *b);
+
+// ec_scalar_sub sets |r| to |a| - |b|.
+void ec_scalar_sub(const EC_GROUP *group, EC_SCALAR *r, const EC_SCALAR *a,
+ const EC_SCALAR *b);
+
+// ec_scalar_neg sets |r| to -|a|.
+void ec_scalar_neg(const EC_GROUP *group, EC_SCALAR *r, const EC_SCALAR *a);
+
+// ec_scalar_to_montgomery sets |r| to |a| in Montgomery form.
+void ec_scalar_to_montgomery(const EC_GROUP *group, EC_SCALAR *r,
+ const EC_SCALAR *a);
+
+// ec_scalar_to_montgomery sets |r| to |a| converted from Montgomery form.
+void ec_scalar_from_montgomery(const EC_GROUP *group, EC_SCALAR *r,
+ const EC_SCALAR *a);
+
+// ec_scalar_mul_montgomery sets |r| to |a| * |b| where inputs and outputs are
+// in Montgomery form.
+void ec_scalar_mul_montgomery(const EC_GROUP *group, EC_SCALAR *r,
+ const EC_SCALAR *a, const EC_SCALAR *b);
+
+// ec_scalar_inv0_montgomery sets |r| to |a|^-1 where inputs and outputs are in
+// Montgomery form. If |a| is zero, |r| is set to zero.
+void ec_scalar_inv0_montgomery(const EC_GROUP *group, EC_SCALAR *r,
+ const EC_SCALAR *a);
+
+// ec_scalar_to_montgomery_inv_vartime sets |r| to |a|^-1 R. That is, it takes
+// in |a| not in Montgomery form and computes the inverse in Montgomery form. It
+// returns one on success and zero if |a| has no inverse. This function assumes
+// |a| is public and may leak information about it via timing.
+//
+// Note this is not the same operation as |ec_scalar_inv0_montgomery|.
+int ec_scalar_to_montgomery_inv_vartime(const EC_GROUP *group, EC_SCALAR *r,
+ const EC_SCALAR *a);
+
+// ec_scalar_select, in constant time, sets |out| to |a| if |mask| is all ones
+// and |b| if |mask| is all zeros.
+void ec_scalar_select(const EC_GROUP *group, EC_SCALAR *out, BN_ULONG mask,
+ const EC_SCALAR *a, const EC_SCALAR *b);
+
+
+// Field elements.
+
+// An EC_FELEM represents a field element. Only the first |field->width| words
+// are used. An |EC_FELEM| is specific to an |EC_GROUP| and must not be mixed
+// between groups. Additionally, the representation (whether or not elements are
+// represented in Montgomery-form) may vary between |EC_METHOD|s.
+typedef struct {
+ BN_ULONG words[EC_MAX_WORDS];
+} EC_FELEM;
+
+// ec_bignum_to_felem converts |in| to an |EC_FELEM|. It returns one on success
+// and zero if |in| is out of range.
+int ec_bignum_to_felem(const EC_GROUP *group, EC_FELEM *out, const BIGNUM *in);
+
+// ec_felem_to_bignum converts |in| to a |BIGNUM|. It returns one on success and
+// zero on allocation failure.
+int ec_felem_to_bignum(const EC_GROUP *group, BIGNUM *out, const EC_FELEM *in);
+
+// ec_felem_to_bytes serializes |in| as a big-endian bytestring to |out| and
+// sets |*out_len| to the number of bytes written. The number of bytes written
+// is |BN_num_bytes(&group->order)|, which is at most |EC_MAX_BYTES|.
+void ec_felem_to_bytes(const EC_GROUP *group, uint8_t *out, size_t *out_len,
+ const EC_FELEM *in);
+
+// ec_felem_from_bytes deserializes |in| and stores the resulting field element
+// to |out|. It returns one on success and zero if |in| is invalid.
+int ec_felem_from_bytes(const EC_GROUP *group, EC_FELEM *out, const uint8_t *in,
+ size_t len);
+
+// ec_felem_neg sets |out| to -|a|.
+void ec_felem_neg(const EC_GROUP *group, EC_FELEM *out, const EC_FELEM *a);
+
+// ec_felem_add sets |out| to |a| + |b|.
+void ec_felem_add(const EC_GROUP *group, EC_FELEM *out, const EC_FELEM *a,
+ const EC_FELEM *b);
+
+// ec_felem_add sets |out| to |a| - |b|.
+void ec_felem_sub(const EC_GROUP *group, EC_FELEM *out, const EC_FELEM *a,
+ const EC_FELEM *b);
+
+// ec_felem_non_zero_mask returns all ones if |a| is non-zero and all zeros
+// otherwise.
+BN_ULONG ec_felem_non_zero_mask(const EC_GROUP *group, const EC_FELEM *a);
+
+// ec_felem_select, in constant time, sets |out| to |a| if |mask| is all ones
+// and |b| if |mask| is all zeros.
+void ec_felem_select(const EC_GROUP *group, EC_FELEM *out, BN_ULONG mask,
+ const EC_FELEM *a, const EC_FELEM *b);
+
+// ec_felem_equal returns one if |a| and |b| are equal and zero otherwise.
+int ec_felem_equal(const EC_GROUP *group, const EC_FELEM *a, const EC_FELEM *b);
+
+
+// Points.
+//
+// Points may represented in affine coordinates as |EC_AFFINE| or Jacobian
+// coordinates as |EC_JACOBIAN|. Affine coordinates directly represent a
+// point on the curve, but point addition over affine coordinates requires
+// costly field inversions, so arithmetic is done in Jacobian coordinates.
+// Converting from affine to Jacobian is cheap, while converting from Jacobian
+// to affine costs a field inversion. (Jacobian coordinates amortize the field
+// inversions needed in a sequence of point operations.)
+
+// An EC_JACOBIAN represents an elliptic curve point in Jacobian coordinates.
+// Unlike |EC_POINT|, it is a plain struct which can be stack-allocated and
+// needs no cleanup. It is specific to an |EC_GROUP| and must not be mixed
+// between groups.
+typedef struct {
+ // X, Y, and Z are Jacobian projective coordinates. They represent
+ // (X/Z^2, Y/Z^3) if Z != 0 and the point at infinity otherwise.
+ EC_FELEM X, Y, Z;
+} EC_JACOBIAN;
+
+// An EC_AFFINE represents an elliptic curve point in affine coordinates.
+// coordinates. Note the point at infinity cannot be represented in affine
+// coordinates.
+typedef struct {
+ EC_FELEM X, Y;
+} EC_AFFINE;
+
+// ec_affine_to_jacobian converts |p| to Jacobian form and writes the result to
+// |*out|. This operation is very cheap and only costs a few copies.
+void ec_affine_to_jacobian(const EC_GROUP *group, EC_JACOBIAN *out,
+ const EC_AFFINE *p);
+
+// ec_jacobian_to_affine converts |p| to affine form and writes the result to
+// |*out|. It returns one on success and zero if |p| was the point at infinity.
+// This operation performs a field inversion and should only be done once per
+// point.
+//
+// If only extracting the x-coordinate, use |ec_get_x_coordinate_*| which is
+// slightly faster.
+OPENSSL_EXPORT int ec_jacobian_to_affine(const EC_GROUP *group, EC_AFFINE *out,
+ const EC_JACOBIAN *p);
+
+// ec_jacobian_to_affine_batch converts |num| points in |in| from Jacobian
+// coordinates to affine coordinates and writes the results to |out|. It returns
+// one on success and zero if any of the input points were infinity.
+//
+// This function is not implemented for all curves. Add implementations as
+// needed.
+int ec_jacobian_to_affine_batch(const EC_GROUP *group, EC_AFFINE *out,
+ const EC_JACOBIAN *in, size_t num);
+
+// ec_point_set_affine_coordinates sets |out|'s to a point with affine
+// coordinates |x| and |y|. It returns one if the point is on the curve and
+// zero otherwise. If the point is not on the curve, the value of |out| is
+// undefined.
+int ec_point_set_affine_coordinates(const EC_GROUP *group, EC_AFFINE *out,
+ const EC_FELEM *x, const EC_FELEM *y);
+
+// ec_point_mul_no_self_test does the same as |EC_POINT_mul|, but doesn't try to
+// run the self-test first. This is for use in the self tests themselves, to
+// prevent an infinite loop.
+int ec_point_mul_no_self_test(const EC_GROUP *group, EC_POINT *r,
+ const BIGNUM *g_scalar, const EC_POINT *p,
+ const BIGNUM *p_scalar, BN_CTX *ctx);
+
+// ec_point_mul_scalar sets |r| to |p| * |scalar|. Both inputs are considered
+// secret.
+int ec_point_mul_scalar(const EC_GROUP *group, EC_JACOBIAN *r,
+ const EC_JACOBIAN *p, const EC_SCALAR *scalar);
+
+// ec_point_mul_scalar_base sets |r| to generator * |scalar|. |scalar| is
+// treated as secret.
+int ec_point_mul_scalar_base(const EC_GROUP *group, EC_JACOBIAN *r,
+ const EC_SCALAR *scalar);
+
+// ec_point_mul_scalar_batch sets |r| to |p0| * |scalar0| + |p1| * |scalar1| +
+// |p2| * |scalar2|. |p2| may be NULL to skip that term.
+//
+// The inputs are treated as secret, however, this function leaks information
+// about whether intermediate computations add a point to itself. Callers must
+// ensure that discrete logs between |p0|, |p1|, and |p2| are uniformly
+// distributed and independent of the scalars, which should be uniformly
+// selected and not under the attackers control. This ensures the doubling case
+// will occur with negligible probability.
+//
+// This function is not implemented for all curves. Add implementations as
+// needed.
+//
+// TODO(davidben): This function does not use base point tables. For now, it is
+// only used with the generic |EC_GFp_mont_method| implementation which has
+// none. If generalizing to tuned curves, this may be useful. However, we still
+// must double up to the least efficient input, so precomputed tables can only
+// save table setup and allow a wider window size.
+int ec_point_mul_scalar_batch(const EC_GROUP *group, EC_JACOBIAN *r,
+ const EC_JACOBIAN *p0, const EC_SCALAR *scalar0,
+ const EC_JACOBIAN *p1, const EC_SCALAR *scalar1,
+ const EC_JACOBIAN *p2, const EC_SCALAR *scalar2);
+
+#define EC_MONT_PRECOMP_COMB_SIZE 5
+
+// An |EC_PRECOMP| stores precomputed information about a point, to optimize
+// repeated multiplications involving it. It is a union so different
+// |EC_METHOD|s can store different information in it.
+typedef union {
+ EC_AFFINE comb[(1 << EC_MONT_PRECOMP_COMB_SIZE) - 1];
+} EC_PRECOMP;
+
+// ec_init_precomp precomputes multiples of |p| and writes the result to |out|.
+// It returns one on success and zero on error. The resulting table may be used
+// with |ec_point_mul_scalar_precomp|. This function will fail if |p| is the
+// point at infinity.
+//
+// This function is not implemented for all curves. Add implementations as
+// needed.
+int ec_init_precomp(const EC_GROUP *group, EC_PRECOMP *out,
+ const EC_JACOBIAN *p);
+
+// ec_point_mul_scalar_precomp sets |r| to |p0| * |scalar0| + |p1| * |scalar1| +
+// |p2| * |scalar2|. |p1| or |p2| may be NULL to skip the corresponding term.
+// The points are represented as |EC_PRECOMP| and must be initialized with
+// |ec_init_precomp|. This function runs faster than |ec_point_mul_scalar_batch|
+// but requires setup work per input point, so it is only appropriate for points
+// which are used frequently.
+//
+// The inputs are treated as secret, however, this function leaks information
+// about whether intermediate computations add a point to itself. Callers must
+// ensure that discrete logs between |p0|, |p1|, and |p2| are uniformly
+// distributed and independent of the scalars, which should be uniformly
+// selected and not under the attackers control. This ensures the doubling case
+// will occur with negligible probability.
+//
+// This function is not implemented for all curves. Add implementations as
+// needed.
+//
+// TODO(davidben): This function does not use base point tables. For now, it is
+// only used with the generic |EC_GFp_mont_method| implementation which has
+// none. If generalizing to tuned curves, we should add a parameter for the base
+// point and arrange for the generic implementation to have base point tables
+// available.
+int ec_point_mul_scalar_precomp(const EC_GROUP *group, EC_JACOBIAN *r,
+ const EC_PRECOMP *p0, const EC_SCALAR *scalar0,
+ const EC_PRECOMP *p1, const EC_SCALAR *scalar1,
+ const EC_PRECOMP *p2, const EC_SCALAR *scalar2);
+
+// ec_point_mul_scalar_public sets |r| to
+// generator * |g_scalar| + |p| * |p_scalar|. It assumes that the inputs are
+// public so there is no concern about leaking their values through timing.
+OPENSSL_EXPORT int ec_point_mul_scalar_public(const EC_GROUP *group,
+ EC_JACOBIAN *r,
+ const EC_SCALAR *g_scalar,
+ const EC_JACOBIAN *p,
+ const EC_SCALAR *p_scalar);
+
+// ec_point_mul_scalar_public_batch sets |r| to the sum of generator *
+// |g_scalar| and |points[i]| * |scalars[i]| where |points| and |scalars| have
+// |num| elements. It assumes that the inputs are public so there is no concern
+// about leaking their values through timing. |g_scalar| may be NULL to skip
+// that term.
+//
+// This function is not implemented for all curves. Add implementations as
+// needed.
+int ec_point_mul_scalar_public_batch(const EC_GROUP *group, EC_JACOBIAN *r,
+ const EC_SCALAR *g_scalar,
+ const EC_JACOBIAN *points,
+ const EC_SCALAR *scalars, size_t num);
+
+// ec_point_select, in constant time, sets |out| to |a| if |mask| is all ones
+// and |b| if |mask| is all zeros.
+void ec_point_select(const EC_GROUP *group, EC_JACOBIAN *out, BN_ULONG mask,
+ const EC_JACOBIAN *a, const EC_JACOBIAN *b);
+
+// ec_affine_select behaves like |ec_point_select| but acts on affine points.
+void ec_affine_select(const EC_GROUP *group, EC_AFFINE *out, BN_ULONG mask,
+ const EC_AFFINE *a, const EC_AFFINE *b);
+
+// ec_precomp_select behaves like |ec_point_select| but acts on |EC_PRECOMP|.
+void ec_precomp_select(const EC_GROUP *group, EC_PRECOMP *out, BN_ULONG mask,
+ const EC_PRECOMP *a, const EC_PRECOMP *b);
+
+// ec_cmp_x_coordinate compares the x (affine) coordinate of |p|, mod the group
+// order, with |r|. It returns one if the values match and zero if |p| is the
+// point at infinity of the values do not match.
+int ec_cmp_x_coordinate(const EC_GROUP *group, const EC_JACOBIAN *p,
+ const EC_SCALAR *r);
+
+// ec_get_x_coordinate_as_scalar sets |*out| to |p|'s x-coordinate, modulo
+// |group->order|. It returns one on success and zero if |p| is the point at
+// infinity.
+int ec_get_x_coordinate_as_scalar(const EC_GROUP *group, EC_SCALAR *out,
+ const EC_JACOBIAN *p);
+
+// ec_get_x_coordinate_as_bytes writes |p|'s affine x-coordinate to |out|, which
+// must have at must |max_out| bytes. It sets |*out_len| to the number of bytes
+// written. The value is written big-endian and zero-padded to the size of the
+// field. This function returns one on success and zero on failure.
+int ec_get_x_coordinate_as_bytes(const EC_GROUP *group, uint8_t *out,
+ size_t *out_len, size_t max_out,
+ const EC_JACOBIAN *p);
+
+// ec_point_byte_len returns the number of bytes in the byte representation of
+// a non-infinity point in |group|, encoded according to |form|, or zero if
+// |form| is invalid.
+size_t ec_point_byte_len(const EC_GROUP *group, point_conversion_form_t form);
+
+// ec_point_to_bytes encodes |point| according to |form| and writes the result
+// |buf|. It returns the size of the output on success or zero on error. At most
+// |max_out| bytes will be written. The buffer should be at least
+// |ec_point_byte_len| long to guarantee success.
+size_t ec_point_to_bytes(const EC_GROUP *group, const EC_AFFINE *point,
+ point_conversion_form_t form, uint8_t *buf,
+ size_t max_out);
+
+// ec_point_from_uncompressed parses |in| as a point in uncompressed form and
+// sets the result to |out|. It returns one on success and zero if the input was
+// invalid.
+int ec_point_from_uncompressed(const EC_GROUP *group, EC_AFFINE *out,
+ const uint8_t *in, size_t len);
+
+// ec_set_to_safe_point sets |out| to an arbitrary point on |group|, either the
+// generator or the point at infinity. This is used to guard against callers of
+// external APIs not checking the return value.
+void ec_set_to_safe_point(const EC_GROUP *group, EC_JACOBIAN *out);
+
+// ec_affine_jacobian_equal returns one if |a| and |b| represent the same point
+// and zero otherwise. It treats both inputs as secret.
+int ec_affine_jacobian_equal(const EC_GROUP *group, const EC_AFFINE *a,
+ const EC_JACOBIAN *b);
+
+
+// Implementation details.
+
+struct ec_method_st {
+ int (*group_init)(EC_GROUP *);
+ void (*group_finish)(EC_GROUP *);
+ int (*group_set_curve)(EC_GROUP *, const BIGNUM *p, const BIGNUM *a,
+ const BIGNUM *b, BN_CTX *);
+
+ // point_get_affine_coordinates sets |*x| and |*y| to the affine coordinates
+ // of |p|. Either |x| or |y| may be NULL to omit it. It returns one on success
+ // and zero if |p| is the point at infinity.
+ int (*point_get_affine_coordinates)(const EC_GROUP *, const EC_JACOBIAN *p,
+ EC_FELEM *x, EC_FELEM *y);
+
+ // jacobian_to_affine_batch implements |ec_jacobian_to_affine_batch|.
+ int (*jacobian_to_affine_batch)(const EC_GROUP *group, EC_AFFINE *out,
+ const EC_JACOBIAN *in, size_t num);
+
+ // add sets |r| to |a| + |b|.
+ void (*add)(const EC_GROUP *group, EC_JACOBIAN *r, const EC_JACOBIAN *a,
+ const EC_JACOBIAN *b);
+ // dbl sets |r| to |a| + |a|.
+ void (*dbl)(const EC_GROUP *group, EC_JACOBIAN *r, const EC_JACOBIAN *a);
+
+ // mul sets |r| to |scalar|*|p|.
+ void (*mul)(const EC_GROUP *group, EC_JACOBIAN *r, const EC_JACOBIAN *p,
+ const EC_SCALAR *scalar);
+ // mul_base sets |r| to |scalar|*generator.
+ void (*mul_base)(const EC_GROUP *group, EC_JACOBIAN *r,
+ const EC_SCALAR *scalar);
+ // mul_batch implements |ec_mul_scalar_batch|.
+ void (*mul_batch)(const EC_GROUP *group, EC_JACOBIAN *r,
+ const EC_JACOBIAN *p0, const EC_SCALAR *scalar0,
+ const EC_JACOBIAN *p1, const EC_SCALAR *scalar1,
+ const EC_JACOBIAN *p2, const EC_SCALAR *scalar2);
+ // mul_public sets |r| to |g_scalar|*generator + |p_scalar|*|p|. It assumes
+ // that the inputs are public so there is no concern about leaking their
+ // values through timing.
+ //
+ // This function may be omitted if |mul_public_batch| is provided.
+ void (*mul_public)(const EC_GROUP *group, EC_JACOBIAN *r,
+ const EC_SCALAR *g_scalar, const EC_JACOBIAN *p,
+ const EC_SCALAR *p_scalar);
+ // mul_public_batch implements |ec_point_mul_scalar_public_batch|.
+ int (*mul_public_batch)(const EC_GROUP *group, EC_JACOBIAN *r,
+ const EC_SCALAR *g_scalar, const EC_JACOBIAN *points,
+ const EC_SCALAR *scalars, size_t num);
+
+ // init_precomp implements |ec_init_precomp|.
+ int (*init_precomp)(const EC_GROUP *group, EC_PRECOMP *out,
+ const EC_JACOBIAN *p);
+ // mul_precomp implements |ec_point_mul_scalar_precomp|.
+ void (*mul_precomp)(const EC_GROUP *group, EC_JACOBIAN *r,
+ const EC_PRECOMP *p0, const EC_SCALAR *scalar0,
+ const EC_PRECOMP *p1, const EC_SCALAR *scalar1,
+ const EC_PRECOMP *p2, const EC_SCALAR *scalar2);
+
+ // felem_mul and felem_sqr implement multiplication and squaring,
+ // respectively, so that the generic |EC_POINT_add| and |EC_POINT_dbl|
+ // implementations can work both with |EC_GFp_mont_method| and the tuned
+ // operations.
+ //
+ // TODO(davidben): This constrains |EC_FELEM|'s internal representation, adds
+ // many indirect calls in the middle of the generic code, and a bunch of
+ // conversions. If p224-64.c were easily convertable to Montgomery form, we
+ // could say |EC_FELEM| is always in Montgomery form. If we routed the rest of
+ // simple.c to |EC_METHOD|, we could give |EC_POINT| an |EC_METHOD|-specific
+ // representation and say |EC_FELEM| is purely a |EC_GFp_mont_method| type.
+ void (*felem_mul)(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a,
+ const EC_FELEM *b);
+ void (*felem_sqr)(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a);
+
+ void (*felem_to_bytes)(const EC_GROUP *group, uint8_t *out, size_t *out_len,
+ const EC_FELEM *in);
+ int (*felem_from_bytes)(const EC_GROUP *group, EC_FELEM *out,
+ const uint8_t *in, size_t len);
+
+ // felem_reduce sets |out| to |words|, reduced modulo the field size, p.
+ // |words| must be less than p^2. |num| must be at most twice the width of p.
+ // This function treats |words| as secret.
+ //
+ // This function is only used in hash-to-curve and may be omitted in curves
+ // that do not support it.
+ void (*felem_reduce)(const EC_GROUP *group, EC_FELEM *out,
+ const BN_ULONG *words, size_t num);
+
+ // felem_exp sets |out| to |a|^|exp|. It treats |a| is secret but |exp| as
+ // public.
+ //
+ // This function is used in hash-to-curve and may be NULL in curves not used
+ // with hash-to-curve.
+ //
+ // TODO(https://crbug.com/boringssl/567): hash-to-curve uses this as part of
+ // computing a square root, which is what compressed coordinates ultimately
+ // needs to avoid |BIGNUM|. Can we unify this a bit? By generalizing to
+ // arbitrary exponentiation, we also miss an opportunity to use a specialized
+ // addition chain.
+ void (*felem_exp)(const EC_GROUP *group, EC_FELEM *out, const EC_FELEM *a,
+ const BN_ULONG *exp, size_t num_exp);
+
+ // scalar_inv0_montgomery implements |ec_scalar_inv0_montgomery|.
+ void (*scalar_inv0_montgomery)(const EC_GROUP *group, EC_SCALAR *out,
+ const EC_SCALAR *in);
+
+ // scalar_to_montgomery_inv_vartime implements
+ // |ec_scalar_to_montgomery_inv_vartime|.
+ int (*scalar_to_montgomery_inv_vartime)(const EC_GROUP *group, EC_SCALAR *out,
+ const EC_SCALAR *in);
+
+ // cmp_x_coordinate compares the x (affine) coordinate of |p|, mod the group
+ // order, with |r|. It returns one if the values match and zero if |p| is the
+ // point at infinity of the values do not match.
+ int (*cmp_x_coordinate)(const EC_GROUP *group, const EC_JACOBIAN *p,
+ const EC_SCALAR *r);
+} /* EC_METHOD */;
+
+const EC_METHOD *EC_GFp_mont_method(void);
+
+struct ec_group_st {
+ const EC_METHOD *meth;
+
+ // Unlike all other |EC_POINT|s, |generator| does not own |generator->group|
+ // to avoid a reference cycle. Additionally, Z is guaranteed to be one, so X
+ // and Y are suitable for use as an |EC_AFFINE|.
+ EC_POINT *generator;
+ BIGNUM order;
+
+ int curve_name; // optional NID for named curve
+
+ BN_MONT_CTX *order_mont; // data for ECDSA inverse
+
+ // The following members are handled by the method functions,
+ // even if they appear generic
+
+ BIGNUM field; // For curves over GF(p), this is the modulus.
+
+ EC_FELEM a, b; // Curve coefficients.
+
+ // a_is_minus3 is one if |a| is -3 mod |field| and zero otherwise. Point
+ // arithmetic is optimized for -3.
+ int a_is_minus3;
+
+ // field_greater_than_order is one if |field| is greate than |order| and zero
+ // otherwise.
+ int field_greater_than_order;
+
+ // field_minus_order, if |field_greater_than_order| is true, is |field| minus
+ // |order| represented as an |EC_FELEM|. Otherwise, it is zero.
+ //
+ // Note: unlike |EC_FELEM|s used as intermediate values internal to the
+ // |EC_METHOD|, this value is not encoded in Montgomery form.
+ EC_FELEM field_minus_order;
+
+ CRYPTO_refcount_t references;
+
+ BN_MONT_CTX *mont; // Montgomery structure.
+
+ EC_FELEM one; // The value one.
+} /* EC_GROUP */;
+
+struct ec_point_st {
+ // group is an owning reference to |group|, unless this is
+ // |group->generator|.
+ EC_GROUP *group;
+ // raw is the group-specific point data. Functions that take |EC_POINT|
+ // typically check consistency with |EC_GROUP| while functions that take
+ // |EC_JACOBIAN| do not. Thus accesses to this field should be externally
+ // checked for consistency.
+ EC_JACOBIAN raw;
+} /* EC_POINT */;
+
+EC_GROUP *ec_group_new(const EC_METHOD *meth);
+
+void ec_GFp_mont_mul(const EC_GROUP *group, EC_JACOBIAN *r,
+ const EC_JACOBIAN *p, const EC_SCALAR *scalar);
+void ec_GFp_mont_mul_base(const EC_GROUP *group, EC_JACOBIAN *r,
+ const EC_SCALAR *scalar);
+void ec_GFp_mont_mul_batch(const EC_GROUP *group, EC_JACOBIAN *r,
+ const EC_JACOBIAN *p0, const EC_SCALAR *scalar0,
+ const EC_JACOBIAN *p1, const EC_SCALAR *scalar1,
+ const EC_JACOBIAN *p2, const EC_SCALAR *scalar2);
+int ec_GFp_mont_init_precomp(const EC_GROUP *group, EC_PRECOMP *out,
+ const EC_JACOBIAN *p);
+void ec_GFp_mont_mul_precomp(const EC_GROUP *group, EC_JACOBIAN *r,
+ const EC_PRECOMP *p0, const EC_SCALAR *scalar0,
+ const EC_PRECOMP *p1, const EC_SCALAR *scalar1,
+ const EC_PRECOMP *p2, const EC_SCALAR *scalar2);
+void ec_GFp_mont_felem_reduce(const EC_GROUP *group, EC_FELEM *out,
+ const BN_ULONG *words, size_t num);
+void ec_GFp_mont_felem_exp(const EC_GROUP *group, EC_FELEM *out,
+ const EC_FELEM *a, const BN_ULONG *exp,
+ size_t num_exp);
+
+// ec_compute_wNAF writes the modified width-(w+1) Non-Adjacent Form (wNAF) of
+// |scalar| to |out|. |out| must have room for |bits| + 1 elements, each of
+// which will be either zero or odd with an absolute value less than 2^w
+// satisfying
+// scalar = \sum_j out[j]*2^j
+// where at most one of any w+1 consecutive digits is non-zero
+// with the exception that the most significant digit may be only
+// w-1 zeros away from that next non-zero digit.
+void ec_compute_wNAF(const EC_GROUP *group, int8_t *out,
+ const EC_SCALAR *scalar, size_t bits, int w);
+
+int ec_GFp_mont_mul_public_batch(const EC_GROUP *group, EC_JACOBIAN *r,
+ const EC_SCALAR *g_scalar,
+ const EC_JACOBIAN *points,
+ const EC_SCALAR *scalars, size_t num);
+
+// method functions in simple.c
+int ec_GFp_simple_group_init(EC_GROUP *);
+void ec_GFp_simple_group_finish(EC_GROUP *);
+int ec_GFp_simple_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a,
+ const BIGNUM *b, BN_CTX *);
+int ec_GFp_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a,
+ BIGNUM *b);
+void ec_GFp_simple_point_init(EC_JACOBIAN *);
+void ec_GFp_simple_point_copy(EC_JACOBIAN *, const EC_JACOBIAN *);
+void ec_GFp_simple_point_set_to_infinity(const EC_GROUP *, EC_JACOBIAN *);
+void ec_GFp_mont_add(const EC_GROUP *, EC_JACOBIAN *r, const EC_JACOBIAN *a,
+ const EC_JACOBIAN *b);
+void ec_GFp_mont_dbl(const EC_GROUP *, EC_JACOBIAN *r, const EC_JACOBIAN *a);
+void ec_GFp_simple_invert(const EC_GROUP *, EC_JACOBIAN *);
+int ec_GFp_simple_is_at_infinity(const EC_GROUP *, const EC_JACOBIAN *);
+int ec_GFp_simple_is_on_curve(const EC_GROUP *, const EC_JACOBIAN *);
+int ec_GFp_simple_points_equal(const EC_GROUP *, const EC_JACOBIAN *a,
+ const EC_JACOBIAN *b);
+void ec_simple_scalar_inv0_montgomery(const EC_GROUP *group, EC_SCALAR *r,
+ const EC_SCALAR *a);
+
+int ec_simple_scalar_to_montgomery_inv_vartime(const EC_GROUP *group,
+ EC_SCALAR *r,
+ const EC_SCALAR *a);
+
+int ec_GFp_simple_cmp_x_coordinate(const EC_GROUP *group, const EC_JACOBIAN *p,
+ const EC_SCALAR *r);
+
+void ec_GFp_simple_felem_to_bytes(const EC_GROUP *group, uint8_t *out,
+ size_t *out_len, const EC_FELEM *in);
+int ec_GFp_simple_felem_from_bytes(const EC_GROUP *group, EC_FELEM *out,
+ const uint8_t *in, size_t len);
+
+// method functions in montgomery.c
+int ec_GFp_mont_group_init(EC_GROUP *);
+int ec_GFp_mont_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a,
+ const BIGNUM *b, BN_CTX *);
+void ec_GFp_mont_group_finish(EC_GROUP *);
+void ec_GFp_mont_felem_mul(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a,
+ const EC_FELEM *b);
+void ec_GFp_mont_felem_sqr(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a);
+
+void ec_GFp_mont_felem_to_bytes(const EC_GROUP *group, uint8_t *out,
+ size_t *out_len, const EC_FELEM *in);
+int ec_GFp_mont_felem_from_bytes(const EC_GROUP *group, EC_FELEM *out,
+ const uint8_t *in, size_t len);
+
+void ec_GFp_nistp_recode_scalar_bits(crypto_word_t *sign, crypto_word_t *digit,
+ crypto_word_t in);
+
+const EC_METHOD *EC_GFp_nistp224_method(void);
+const EC_METHOD *EC_GFp_nistp256_method(void);
+
+// EC_GFp_nistz256_method is a GFp method using montgomery multiplication, with
+// x86-64 optimized P256. See http://eprint.iacr.org/2013/816.
+const EC_METHOD *EC_GFp_nistz256_method(void);
+
+// An EC_WRAPPED_SCALAR is an |EC_SCALAR| with a parallel |BIGNUM|
+// representation. It exists to support the |EC_KEY_get0_private_key| API.
+typedef struct {
+ BIGNUM bignum;
+ EC_SCALAR scalar;
+} EC_WRAPPED_SCALAR;
+
+struct ec_key_st {
+ EC_GROUP *group;
+
+ // Ideally |pub_key| would be an |EC_AFFINE| so serializing it does not pay an
+ // inversion each time, but the |EC_KEY_get0_public_key| API implies public
+ // keys are stored in an |EC_POINT|-compatible form.
+ EC_POINT *pub_key;
+ EC_WRAPPED_SCALAR *priv_key;
+
+ unsigned int enc_flag;
+ point_conversion_form_t conv_form;
+
+ CRYPTO_refcount_t references;
+
+ ECDSA_METHOD *ecdsa_meth;
+
+ CRYPTO_EX_DATA ex_data;
+} /* EC_KEY */;
+
+struct built_in_curve {
+ int nid;
+ const uint8_t *oid;
+ uint8_t oid_len;
+ // comment is a human-readable string describing the curve.
+ const char *comment;
+ // param_len is the number of bytes needed to store a field element.
+ uint8_t param_len;
+ // params points to an array of 6*|param_len| bytes which hold the field
+ // elements of the following (in big-endian order): prime, a, b, generator x,
+ // generator y, order.
+ const uint8_t *params;
+ const EC_METHOD *method;
+};
+
+#define OPENSSL_NUM_BUILT_IN_CURVES 4
+
+struct built_in_curves {
+ struct built_in_curve curves[OPENSSL_NUM_BUILT_IN_CURVES];
+};
+
+// OPENSSL_built_in_curves returns a pointer to static information about
+// standard curves. The array is terminated with an entry where |nid| is
+// |NID_undef|.
+const struct built_in_curves *OPENSSL_built_in_curves(void);
+
+#if defined(__cplusplus)
+} // extern C
+#endif
+
+#endif // OPENSSL_HEADER_EC_INTERNAL_H
diff --git a/src/crypto/fipsmodule/ec/make_ec_scalar_base_mult_tests.go b/src/crypto/fipsmodule/ec/make_ec_scalar_base_mult_tests.go
new file mode 100644
index 0000000..1d3896a
--- /dev/null
+++ b/src/crypto/fipsmodule/ec/make_ec_scalar_base_mult_tests.go
@@ -0,0 +1,62 @@
+// Copyright (c) 2018, Google Inc.
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+//go:build ignore
+
+package main
+
+import (
+ "crypto/elliptic"
+ "fmt"
+ "math/big"
+)
+
+const numPoints = 64
+
+func printPadded(key string, n, max *big.Int) {
+ padded := make([]byte, len(max.Bytes()))
+ b := n.Bytes()
+ copy(padded[len(padded)-len(b):], b)
+ fmt.Printf("%s = %x\n", key, padded)
+}
+
+func printMultiples(name string, curve elliptic.Curve) {
+ n := new(big.Int)
+ for i := -numPoints; i <= numPoints; i++ {
+ fmt.Printf("Curve = %s\n", name)
+ n.SetInt64(int64(i))
+ if i < 0 {
+ n = n.Add(n, curve.Params().N)
+ }
+ fmt.Printf("# N = %d\n", i)
+ printPadded("N", n, curve.Params().N)
+ x, y := curve.ScalarBaseMult(n.Bytes())
+ printPadded("X", x, curve.Params().P)
+ printPadded("Y", y, curve.Params().P)
+ fmt.Printf("\n")
+ }
+}
+
+func main() {
+ fmt.Printf(`# This file contains multiples of the base point for various curves. The point
+# at infinity is represented as X = 0, Y = 0.
+#
+# This file is generated by make_ec_scalar_base_mult_tests.go
+
+`)
+ printMultiples("P-224", elliptic.P224())
+ printMultiples("P-256", elliptic.P256())
+ printMultiples("P-384", elliptic.P384())
+ printMultiples("P-521", elliptic.P521())
+}
diff --git a/src/crypto/fipsmodule/ec/make_p256-nistz-tests.go b/src/crypto/fipsmodule/ec/make_p256-nistz-tests.go
new file mode 100644
index 0000000..e10990b
--- /dev/null
+++ b/src/crypto/fipsmodule/ec/make_p256-nistz-tests.go
@@ -0,0 +1,234 @@
+// Copyright (c) 2018, Google Inc.
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+//go:build ignore
+
+package main
+
+import (
+ "crypto/aes"
+ "crypto/cipher"
+ "crypto/elliptic"
+ "crypto/rand"
+ "fmt"
+ "io"
+ "math/big"
+)
+
+var (
+ p256 elliptic.Curve
+ zero, one, p, R, Rinv *big.Int
+ deterministicRand io.Reader
+)
+
+type coordinates int
+
+const (
+ affine coordinates = iota
+ jacobian
+)
+
+func init() {
+ p256 = elliptic.P256()
+
+ zero = new(big.Int)
+ one = new(big.Int).SetInt64(1)
+
+ p = p256.Params().P
+
+ R = new(big.Int)
+ R.SetBit(R, 256, 1)
+ R.Mod(R, p)
+
+ Rinv = new(big.Int).ModInverse(R, p)
+
+ deterministicRand = newDeterministicRand()
+}
+
+func modMul(z, x, y *big.Int) *big.Int {
+ z.Mul(x, y)
+ return z.Mod(z, p)
+}
+
+func toMontgomery(z, x *big.Int) *big.Int {
+ return modMul(z, x, R)
+}
+
+func fromMontgomery(z, x *big.Int) *big.Int {
+ return modMul(z, x, Rinv)
+}
+
+func isAffineInfinity(x, y *big.Int) bool {
+ // Infinity, in affine coordinates, is represented as (0, 0) by
+ // both Go, p256-x86_64-asm.pl and p256-armv8-asm.pl.
+ return x.Sign() == 0 && y.Sign() == 0
+}
+
+func randNonZeroInt(max *big.Int) *big.Int {
+ for {
+ r, err := rand.Int(deterministicRand, max)
+ if err != nil {
+ panic(err)
+ }
+ if r.Sign() != 0 {
+ return r
+ }
+ }
+}
+
+func randPoint() (x, y *big.Int) {
+ k := randNonZeroInt(p256.Params().N)
+ return p256.ScalarBaseMult(k.Bytes())
+}
+
+func toJacobian(xIn, yIn *big.Int) (x, y, z *big.Int) {
+ if isAffineInfinity(xIn, yIn) {
+ // The Jacobian representation of infinity has Z = 0. Depending
+ // on the implementation, X and Y may be further constrained.
+ // Generalizing the curve equation to Jacobian coordinates for
+ // non-zero Z gives:
+ //
+ // y² = x³ - 3x + b, where x = X/Z² and y = Y/Z³
+ // Y² = X³ + aXZ⁴ + bZ⁶
+ //
+ // Taking that formula at Z = 0 gives Y² = X³. This constraint
+ // allows removing a special case in the point-on-curve check.
+ //
+ // BoringSSL, however, historically generated infinities with
+ // arbitrary X and Y and include the special case. We also have
+ // not verified that add and double preserve this
+ // property. Thus, generate test vectors with unrelated X and Y,
+ // to test that p256-x86_64-asm.pl and p256-armv8-asm.pl correctly
+ // handle unconstrained representations of infinity.
+ x = randNonZeroInt(p)
+ y = randNonZeroInt(p)
+ z = zero
+ return
+ }
+
+ z = randNonZeroInt(p)
+
+ // X = xZ²
+ y = modMul(new(big.Int), z, z)
+ x = modMul(new(big.Int), xIn, y)
+
+ // Y = yZ³
+ modMul(y, y, z)
+ modMul(y, y, yIn)
+ return
+}
+
+func printMontgomery(name string, a *big.Int) {
+ a = toMontgomery(new(big.Int), a)
+ fmt.Printf("%s = %064x\n", name, a)
+}
+
+func printTestCase(ax, ay *big.Int, aCoord coordinates, bx, by *big.Int, bCoord coordinates) {
+ rx, ry := p256.Add(ax, ay, bx, by)
+
+ var az *big.Int
+ if aCoord == jacobian {
+ ax, ay, az = toJacobian(ax, ay)
+ } else if isAffineInfinity(ax, ay) {
+ az = zero
+ } else {
+ az = one
+ }
+
+ var bz *big.Int
+ if bCoord == jacobian {
+ bx, by, bz = toJacobian(bx, by)
+ } else if isAffineInfinity(bx, by) {
+ bz = zero
+ } else {
+ bz = one
+ }
+
+ fmt.Printf("Test = PointAdd\n")
+ printMontgomery("A.X", ax)
+ printMontgomery("A.Y", ay)
+ printMontgomery("A.Z", az)
+ printMontgomery("B.X", bx)
+ printMontgomery("B.Y", by)
+ printMontgomery("B.Z", bz)
+ printMontgomery("Result.X", rx)
+ printMontgomery("Result.Y", ry)
+ fmt.Printf("\n")
+}
+
+func main() {
+ fmt.Printf("# ∞ + ∞ = ∞.\n")
+ printTestCase(zero, zero, affine, zero, zero, affine)
+
+ fmt.Printf("# ∞ + ∞ = ∞, with an alternate representation of ∞.\n")
+ printTestCase(zero, zero, jacobian, zero, zero, jacobian)
+
+ gx, gy := p256.Params().Gx, p256.Params().Gy
+ fmt.Printf("# g + ∞ = g.\n")
+ printTestCase(gx, gy, affine, zero, zero, affine)
+
+ fmt.Printf("# g + ∞ = g, with an alternate representation of ∞.\n")
+ printTestCase(gx, gy, affine, zero, zero, jacobian)
+
+ fmt.Printf("# g + -g = ∞.\n")
+ minusGy := new(big.Int).Sub(p, gy)
+ printTestCase(gx, gy, affine, gx, minusGy, affine)
+
+ fmt.Printf("# Test some random Jacobian sums.\n")
+ for i := 0; i < 4; i++ {
+ ax, ay := randPoint()
+ bx, by := randPoint()
+ printTestCase(ax, ay, jacobian, bx, by, jacobian)
+ }
+
+ fmt.Printf("# Test some random Jacobian doublings.\n")
+ for i := 0; i < 4; i++ {
+ ax, ay := randPoint()
+ printTestCase(ax, ay, jacobian, ax, ay, jacobian)
+ }
+
+ fmt.Printf("# Test some random affine sums.\n")
+ for i := 0; i < 4; i++ {
+ ax, ay := randPoint()
+ bx, by := randPoint()
+ printTestCase(ax, ay, affine, bx, by, affine)
+ }
+
+ fmt.Printf("# Test some random affine doublings.\n")
+ for i := 0; i < 4; i++ {
+ ax, ay := randPoint()
+ printTestCase(ax, ay, affine, ax, ay, affine)
+ }
+}
+
+type deterministicRandom struct {
+ stream cipher.Stream
+}
+
+func newDeterministicRand() io.Reader {
+ block, err := aes.NewCipher(make([]byte, 128/8))
+ if err != nil {
+ panic(err)
+ }
+ stream := cipher.NewCTR(block, make([]byte, block.BlockSize()))
+ return &deterministicRandom{stream}
+}
+
+func (r *deterministicRandom) Read(b []byte) (n int, err error) {
+ for i := range b {
+ b[i] = 0
+ }
+ r.stream.XORKeyStream(b, b)
+ return len(b), nil
+}
diff --git a/src/crypto/fipsmodule/ec/make_tables.go b/src/crypto/fipsmodule/ec/make_tables.go
new file mode 100644
index 0000000..120c40b
--- /dev/null
+++ b/src/crypto/fipsmodule/ec/make_tables.go
@@ -0,0 +1,408 @@
+// Copyright (c) 2020, Google Inc.
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+//go:build ignore
+
+package main
+
+import (
+ "crypto/elliptic"
+ "fmt"
+ "io"
+ "math/big"
+ "os"
+)
+
+func main() {
+ if err := writeP256NistzTable("p256-nistz-table.h"); err != nil {
+ fmt.Fprintf(os.Stderr, "Error writing p256-nistz-table.h: %s\n", err)
+ os.Exit(1)
+ }
+
+ if err := writeP256Table("p256_table.h"); err != nil {
+ fmt.Fprintf(os.Stderr, "Error writing p256_table.h: %s\n", err)
+ os.Exit(1)
+ }
+}
+
+func writeP256NistzTable(path string) error {
+ curve := elliptic.P256()
+ tables := make([][][2]*big.Int, 0, 37)
+ for shift := 0; shift < 256; shift += 7 {
+ row := makeMultiples(curve, 64, shift)
+ tables = append(tables, row)
+ }
+
+ f, err := os.Create(path)
+ if err != nil {
+ return err
+ }
+ defer f.Close()
+
+ const fileHeader = `/*
+ * Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright (c) 2015, Intel Inc.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+// This is the precomputed constant time access table for the code in
+// p256-nistz.c, for the default generator. The table consists of 37
+// subtables, each subtable contains 64 affine points. The affine points are
+// encoded as eight uint64's, four for the x coordinate and four for the y.
+// Both values are in little-endian order. There are 37 tables because a
+// signed, 6-bit wNAF form of the scalar is used and ceil(256/(6 + 1)) = 37.
+// Within each table there are 64 values because the 6-bit wNAF value can take
+// 64 values, ignoring the sign bit, which is implemented by performing a
+// negation of the affine point when required. We would like to align it to 2MB
+// in order to increase the chances of using a large page but that appears to
+// lead to invalid ELF files being produced.
+
+// This file is generated by make_tables.go.
+
+static const alignas(4096) PRECOMP256_ROW ecp_nistz256_precomputed[37] = `
+ if _, err := f.WriteString(fileHeader); err != nil {
+ return err
+ }
+ if err := writeTables(f, curve, tables, true, 4, writeBNMont); err != nil {
+ return err
+ }
+ if _, err := f.WriteString(";\n"); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func writeP256Table(path string) error {
+ curve := elliptic.P256()
+ tables := [][][2]*big.Int{
+ makeComb(curve, 64, 4, 0),
+ makeComb(curve, 64, 4, 32),
+ }
+
+ f, err := os.Create(path)
+ if err != nil {
+ return err
+ }
+ defer f.Close()
+
+ const fileHeader = `/* Copyright (c) 2020, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+// This file is generated by make_tables.go.
+
+// Base point pre computation
+// --------------------------
+//
+// Two different sorts of precomputed tables are used in the following code.
+// Each contain various points on the curve, where each point is three field
+// elements (x, y, z).
+//
+// For the base point table, z is usually 1 (0 for the point at infinity).
+// This table has 2 * 16 elements, starting with the following:
+// index | bits | point
+// ------+---------+------------------------------
+// 0 | 0 0 0 0 | 0G
+// 1 | 0 0 0 1 | 1G
+// 2 | 0 0 1 0 | 2^64G
+// 3 | 0 0 1 1 | (2^64 + 1)G
+// 4 | 0 1 0 0 | 2^128G
+// 5 | 0 1 0 1 | (2^128 + 1)G
+// 6 | 0 1 1 0 | (2^128 + 2^64)G
+// 7 | 0 1 1 1 | (2^128 + 2^64 + 1)G
+// 8 | 1 0 0 0 | 2^192G
+// 9 | 1 0 0 1 | (2^192 + 1)G
+// 10 | 1 0 1 0 | (2^192 + 2^64)G
+// 11 | 1 0 1 1 | (2^192 + 2^64 + 1)G
+// 12 | 1 1 0 0 | (2^192 + 2^128)G
+// 13 | 1 1 0 1 | (2^192 + 2^128 + 1)G
+// 14 | 1 1 1 0 | (2^192 + 2^128 + 2^64)G
+// 15 | 1 1 1 1 | (2^192 + 2^128 + 2^64 + 1)G
+// followed by a copy of this with each element multiplied by 2^32.
+//
+// The reason for this is so that we can clock bits into four different
+// locations when doing simple scalar multiplies against the base point,
+// and then another four locations using the second 16 elements.
+//
+// Tables for other points have table[i] = iG for i in 0 .. 16.
+
+// fiat_p256_g_pre_comp is the table of precomputed base points
+#if defined(OPENSSL_64_BIT)
+static const fiat_p256_felem fiat_p256_g_pre_comp[2][15][2] = `
+ if _, err := f.WriteString(fileHeader); err != nil {
+ return err
+ }
+ if err := writeTables(f, curve, tables, true, 4, writeU64Mont); err != nil {
+ return err
+ }
+ if _, err := f.WriteString(";\n#else\nstatic const fiat_p256_felem fiat_p256_g_pre_comp[2][15][2] = "); err != nil {
+ return err
+ }
+ if err := writeTables(f, curve, tables, true, 4, writeU32Mont); err != nil {
+ return err
+ }
+ if _, err := f.WriteString(";\n#endif\n"); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+// makeMultiples returns a table of the first n multiples of 2^shift * G,
+// starting from 1 * 2^shift * G.
+func makeMultiples(curve elliptic.Curve, n, shift int) [][2]*big.Int {
+ ret := make([][2]*big.Int, n)
+ x, y := curve.Params().Gx, curve.Params().Gy
+ for j := 0; j < shift; j++ {
+ x, y = curve.Double(x, y)
+ }
+ ret[1-1] = [2]*big.Int{x, y}
+ for i := 2; i <= n; i++ {
+ if i&1 == 0 {
+ x, y := curve.Double(ret[i/2-1][0], ret[i/2-1][1])
+ ret[i-1] = [2]*big.Int{x, y}
+ } else {
+ x, y := curve.Add(ret[i-1-1][0], ret[i-1-1][1], ret[1-1][0], ret[1-1][1])
+ ret[i-1] = [2]*big.Int{x, y}
+ }
+ }
+ return ret
+}
+
+// makeComb returns a table of 2^size - 1 points. The i-1th entry is k*G.
+// If i is represented in binary by b0*2^0 + b1*2^1 + ... bn*2^n, k is
+// b0*2^(shift + 0*stride) + b1*2^(shift + 1*stride) + ... + bn*2^(shift + n*stride).
+// The entry for i = 0 is omitted because it is always the point at infinity.
+func makeComb(curve elliptic.Curve, stride, size, shift int) [][2]*big.Int {
+ ret := make([][2]*big.Int, 1<<size-1)
+ x, y := curve.Params().Gx, curve.Params().Gy
+ for j := 0; j < shift; j++ {
+ x, y = curve.Double(x, y)
+ }
+ ret[1<<0-1] = [2]*big.Int{x, y}
+ for i := 1; i < size; i++ {
+ // Entry 2^i is entry 2^(i-1) doubled stride times.
+ x, y = ret[1<<(i-1)-1][0], ret[1<<(i-1)-1][1]
+ for j := 0; j < stride; j++ {
+ x, y = curve.Double(x, y)
+ }
+ ret[1<<i-1] = [2]*big.Int{x, y}
+ // The remaining entries with MSB 2^i are computed by adding entry 2^i
+ // to the corresponding previous entry.
+ for j := 1; j < 1<<i; j++ {
+ x, y = curve.Add(ret[1<<i-1][0], ret[1<<i-1][1], ret[j-1][0], ret[j-1][1])
+ ret[1<<i+j-1] = [2]*big.Int{x, y}
+ }
+ }
+ return ret
+}
+
+// toMontgomery sets n to be n×R mod p, where R is the Montgomery factor.
+func toMontgomery(curve elliptic.Curve, n *big.Int) *big.Int {
+ params := curve.Params()
+ // R is the bit width of p, rounded up to word size.
+ rounded64 := 64 * ((params.BitSize + 63) / 64)
+ rounded32 := 32 * ((params.BitSize + 31) / 32)
+ if rounded64 != rounded32 {
+ panic(fmt.Sprintf("Montgomery form for %s is inconsistent between 32-bit and 64-bit", params.Name))
+ }
+ R := new(big.Int).SetInt64(1)
+ R.Lsh(R, uint(rounded64))
+
+ ret := new(big.Int).Mul(n, R)
+ ret.Mod(ret, params.P)
+ return ret
+}
+
+func bigIntToU64s(curve elliptic.Curve, n *big.Int) []uint64 {
+ words := (curve.Params().BitSize + 63) / 64
+ ret := make([]uint64, words)
+ bytes := n.Bytes()
+ for i, b := range bytes {
+ i = len(bytes) - i - 1
+ ret[i/8] |= uint64(b) << (8 * (i % 8))
+ }
+ return ret
+}
+
+func bigIntToU32s(curve elliptic.Curve, n *big.Int) []uint64 {
+ words := (curve.Params().BitSize + 31) / 32
+ ret := make([]uint64, words)
+ bytes := n.Bytes()
+ for i, b := range bytes {
+ i = len(bytes) - i - 1
+ ret[i/4] |= uint64(b) << (8 * (i % 4))
+ }
+ return ret
+}
+
+func writeIndent(w io.Writer, indent int) error {
+ for i := 0; i < indent; i++ {
+ if _, err := io.WriteString(w, " "); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func writeWords(w io.Writer, words []uint64, wrap, indent int, format func(uint64) string) error {
+ if _, err := io.WriteString(w, "{"); err != nil {
+ return err
+ }
+ for i, word := range words {
+ if i > 0 {
+ if i%wrap == 0 {
+ if _, err := io.WriteString(w, ",\n"); err != nil {
+ return err
+ }
+ if err := writeIndent(w, indent+1); err != nil {
+ return err
+ }
+ } else {
+ if _, err := io.WriteString(w, ", "); err != nil {
+ return err
+ }
+ }
+ }
+ if _, err := io.WriteString(w, format(word)); err != nil {
+ return err
+ }
+ }
+ if _, err := io.WriteString(w, "}"); err != nil {
+ return err
+ }
+ return nil
+}
+
+func writeBNMont(w io.Writer, curve elliptic.Curve, n *big.Int, indent int) error {
+ n = toMontgomery(curve, n)
+ return writeWords(w, bigIntToU64s(curve, n), 2, indent, func(word uint64) string {
+ return fmt.Sprintf("TOBN(0x%08x, 0x%08x)", uint32(word>>32), uint32(word))
+ })
+}
+
+func writeU64Mont(w io.Writer, curve elliptic.Curve, n *big.Int, indent int) error {
+ n = toMontgomery(curve, n)
+ return writeWords(w, bigIntToU64s(curve, n), 3, indent, func(word uint64) string {
+ return fmt.Sprintf("0x%016x", word)
+ })
+}
+
+func writeU32Mont(w io.Writer, curve elliptic.Curve, n *big.Int, indent int) error {
+ n = toMontgomery(curve, n)
+ return writeWords(w, bigIntToU32s(curve, n), 6, indent, func(word uint64) string {
+ if word >= 1<<32 {
+ panic(fmt.Sprintf("word too large: 0x%x", word))
+ }
+ return fmt.Sprintf("0x%08x", word)
+ })
+}
+
+type writeBigIntFunc func(w io.Writer, curve elliptic.Curve, n *big.Int, indent int) error
+
+func writeTable(w io.Writer, curve elliptic.Curve, table [][2]*big.Int, isRoot bool, indent int, writeBigInt writeBigIntFunc) error {
+ if _, err := io.WriteString(w, "{"); err != nil {
+ return err
+ }
+ if isRoot {
+ if _, err := io.WriteString(w, "\n"); err != nil {
+ return err
+ }
+ if err := writeIndent(w, indent); err != nil {
+ return err
+ }
+ } else {
+ indent++
+ }
+ for i, point := range table {
+ if i != 0 {
+ if _, err := io.WriteString(w, ",\n"); err != nil {
+ return err
+ }
+ if err := writeIndent(w, indent); err != nil {
+ return err
+ }
+ }
+ if _, err := io.WriteString(w, "{"); err != nil {
+ return err
+ }
+ if err := writeBigInt(w, curve, point[0], indent+1); err != nil {
+ return err
+ }
+ if _, err := io.WriteString(w, ",\n"); err != nil {
+ return err
+ }
+ if err := writeIndent(w, indent+1); err != nil {
+ return err
+ }
+ if err := writeBigInt(w, curve, point[1], indent+1); err != nil {
+ return err
+ }
+ if _, err := io.WriteString(w, "}"); err != nil {
+ return err
+ }
+ }
+ if _, err := io.WriteString(w, "}"); err != nil {
+ return err
+ }
+ return nil
+}
+
+func writeTables(w io.Writer, curve elliptic.Curve, tables [][][2]*big.Int, isRoot bool, indent int, writeBigInt writeBigIntFunc) error {
+ if _, err := io.WriteString(w, "{"); err != nil {
+ return err
+ }
+ if isRoot {
+ if _, err := io.WriteString(w, "\n"); err != nil {
+ return err
+ }
+ if err := writeIndent(w, indent); err != nil {
+ return err
+ }
+ } else {
+ indent++
+ }
+ for i, table := range tables {
+ if i != 0 {
+ if _, err := io.WriteString(w, ",\n"); err != nil {
+ return err
+ }
+ if err := writeIndent(w, indent); err != nil {
+ return err
+ }
+ }
+ if err := writeTable(w, curve, table, false, indent, writeBigInt); err != nil {
+ return err
+ }
+ }
+ if _, err := io.WriteString(w, "}"); err != nil {
+ return err
+ }
+ return nil
+}
diff --git a/src/crypto/fipsmodule/ec/oct.c b/src/crypto/fipsmodule/ec/oct.c
new file mode 100644
index 0000000..eb77643
--- /dev/null
+++ b/src/crypto/fipsmodule/ec/oct.c
@@ -0,0 +1,358 @@
+/* Originally written by Bodo Moeller for the OpenSSL project.
+ * ====================================================================
+ * Copyright (c) 1998-2005 The OpenSSL Project. 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.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS 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.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * The elliptic curve binary polynomial software is originally written by
+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems
+ * Laboratories. */
+
+#include <openssl/ec.h>
+
+#include <openssl/bn.h>
+#include <openssl/err.h>
+
+#include "internal.h"
+
+
+size_t ec_point_byte_len(const EC_GROUP *group, point_conversion_form_t form) {
+ if (form != POINT_CONVERSION_COMPRESSED &&
+ form != POINT_CONVERSION_UNCOMPRESSED) {
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_FORM);
+ return 0;
+ }
+
+ const size_t field_len = BN_num_bytes(&group->field);
+ size_t output_len = 1 /* type byte */ + field_len;
+ if (form == POINT_CONVERSION_UNCOMPRESSED) {
+ // Uncompressed points have a second coordinate.
+ output_len += field_len;
+ }
+ return output_len;
+}
+
+size_t ec_point_to_bytes(const EC_GROUP *group, const EC_AFFINE *point,
+ point_conversion_form_t form, uint8_t *buf,
+ size_t max_out) {
+ size_t output_len = ec_point_byte_len(group, form);
+ if (max_out < output_len) {
+ OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL);
+ return 0;
+ }
+
+ size_t field_len;
+ ec_felem_to_bytes(group, buf + 1, &field_len, &point->X);
+ assert(field_len == BN_num_bytes(&group->field));
+
+ if (form == POINT_CONVERSION_UNCOMPRESSED) {
+ ec_felem_to_bytes(group, buf + 1 + field_len, &field_len, &point->Y);
+ assert(field_len == BN_num_bytes(&group->field));
+ buf[0] = form;
+ } else {
+ uint8_t y_buf[EC_MAX_BYTES];
+ ec_felem_to_bytes(group, y_buf, &field_len, &point->Y);
+ buf[0] = form + (y_buf[field_len - 1] & 1);
+ }
+
+ return output_len;
+}
+
+int ec_point_from_uncompressed(const EC_GROUP *group, EC_AFFINE *out,
+ const uint8_t *in, size_t len) {
+ const size_t field_len = BN_num_bytes(&group->field);
+ if (len != 1 + 2 * field_len || in[0] != POINT_CONVERSION_UNCOMPRESSED) {
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING);
+ return 0;
+ }
+
+ EC_FELEM x, y;
+ if (!ec_felem_from_bytes(group, &x, in + 1, field_len) ||
+ !ec_felem_from_bytes(group, &y, in + 1 + field_len, field_len) ||
+ !ec_point_set_affine_coordinates(group, out, &x, &y)) {
+ return 0;
+ }
+
+ return 1;
+}
+
+static int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
+ const uint8_t *buf, size_t len,
+ BN_CTX *ctx) {
+ if (len == 0) {
+ OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL);
+ return 0;
+ }
+
+ point_conversion_form_t form = buf[0];
+ if (form == POINT_CONVERSION_UNCOMPRESSED) {
+ EC_AFFINE affine;
+ if (!ec_point_from_uncompressed(group, &affine, buf, len)) {
+ // In the event of an error, defend against the caller not checking the
+ // return value by setting a known safe value.
+ ec_set_to_safe_point(group, &point->raw);
+ return 0;
+ }
+ ec_affine_to_jacobian(group, &point->raw, &affine);
+ return 1;
+ }
+
+ const int y_bit = form & 1;
+ const size_t field_len = BN_num_bytes(&group->field);
+ form = form & ~1u;
+ if (form != POINT_CONVERSION_COMPRESSED ||
+ len != 1 /* type byte */ + field_len) {
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING);
+ return 0;
+ }
+
+ // TODO(davidben): Integrate compressed coordinates with the lower-level EC
+ // abstractions. This requires a way to compute square roots, which is tricky
+ // for primes which are not 3 (mod 4), namely P-224 and custom curves. P-224's
+ // prime is particularly inconvenient for compressed coordinates. See
+ // https://cr.yp.to/papers/sqroot.pdf
+ BN_CTX *new_ctx = NULL;
+ if (ctx == NULL) {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL) {
+ return 0;
+ }
+ }
+
+ int ret = 0;
+ BN_CTX_start(ctx);
+ BIGNUM *x = BN_CTX_get(ctx);
+ if (x == NULL || !BN_bin2bn(buf + 1, field_len, x)) {
+ goto err;
+ }
+ if (BN_ucmp(x, &group->field) >= 0) {
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING);
+ goto err;
+ }
+
+ if (!EC_POINT_set_compressed_coordinates_GFp(group, point, x, y_bit, ctx)) {
+ goto err;
+ }
+
+ ret = 1;
+
+err:
+ BN_CTX_end(ctx);
+ BN_CTX_free(new_ctx);
+ return ret;
+}
+
+int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point,
+ const uint8_t *buf, size_t len, BN_CTX *ctx) {
+ if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
+ return ec_GFp_simple_oct2point(group, point, buf, len, ctx);
+}
+
+size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point,
+ point_conversion_form_t form, uint8_t *buf,
+ size_t max_out, BN_CTX *ctx) {
+ if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
+ if (buf == NULL) {
+ // When |buf| is NULL, just return the number of bytes that would be
+ // written, without doing an expensive Jacobian-to-affine conversion.
+ if (ec_GFp_simple_is_at_infinity(group, &point->raw)) {
+ OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY);
+ return 0;
+ }
+ return ec_point_byte_len(group, form);
+ }
+ EC_AFFINE affine;
+ if (!ec_jacobian_to_affine(group, &affine, &point->raw)) {
+ return 0;
+ }
+ return ec_point_to_bytes(group, &affine, form, buf, max_out);
+}
+
+size_t EC_POINT_point2buf(const EC_GROUP *group, const EC_POINT *point,
+ point_conversion_form_t form, uint8_t **out_buf,
+ BN_CTX *ctx) {
+ *out_buf = NULL;
+ size_t len = EC_POINT_point2oct(group, point, form, NULL, 0, ctx);
+ if (len == 0) {
+ return 0;
+ }
+ uint8_t *buf = OPENSSL_malloc(len);
+ if (buf == NULL) {
+ return 0;
+ }
+ len = EC_POINT_point2oct(group, point, form, buf, len, ctx);
+ if (len == 0) {
+ OPENSSL_free(buf);
+ return 0;
+ }
+ *out_buf = buf;
+ return len;
+}
+
+int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group,
+ EC_POINT *point, const BIGNUM *x,
+ int y_bit, BN_CTX *ctx) {
+ if (EC_GROUP_cmp(group, point->group, NULL) != 0) {
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
+
+ if (BN_is_negative(x) || BN_cmp(x, &group->field) >= 0) {
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_COMPRESSED_POINT);
+ return 0;
+ }
+
+ BN_CTX *new_ctx = NULL;
+ int ret = 0;
+
+ ERR_clear_error();
+
+ if (ctx == NULL) {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL) {
+ return 0;
+ }
+ }
+
+ y_bit = (y_bit != 0);
+
+ BN_CTX_start(ctx);
+ BIGNUM *tmp1 = BN_CTX_get(ctx);
+ BIGNUM *tmp2 = BN_CTX_get(ctx);
+ BIGNUM *a = BN_CTX_get(ctx);
+ BIGNUM *b = BN_CTX_get(ctx);
+ BIGNUM *y = BN_CTX_get(ctx);
+ if (y == NULL ||
+ !EC_GROUP_get_curve_GFp(group, NULL, a, b, ctx)) {
+ goto err;
+ }
+
+ // Recover y. We have a Weierstrass equation
+ // y^2 = x^3 + a*x + b,
+ // so y is one of the square roots of x^3 + a*x + b.
+
+ // tmp1 := x^3
+ if (!BN_mod_sqr(tmp2, x, &group->field, ctx) ||
+ !BN_mod_mul(tmp1, tmp2, x, &group->field, ctx)) {
+ goto err;
+ }
+
+ // tmp1 := tmp1 + a*x
+ if (group->a_is_minus3) {
+ if (!bn_mod_lshift1_consttime(tmp2, x, &group->field, ctx) ||
+ !bn_mod_add_consttime(tmp2, tmp2, x, &group->field, ctx) ||
+ !bn_mod_sub_consttime(tmp1, tmp1, tmp2, &group->field, ctx)) {
+ goto err;
+ }
+ } else {
+ if (!BN_mod_mul(tmp2, a, x, &group->field, ctx) ||
+ !bn_mod_add_consttime(tmp1, tmp1, tmp2, &group->field, ctx)) {
+ goto err;
+ }
+ }
+
+ // tmp1 := tmp1 + b
+ if (!bn_mod_add_consttime(tmp1, tmp1, b, &group->field, ctx)) {
+ goto err;
+ }
+
+ if (!BN_mod_sqrt(y, tmp1, &group->field, ctx)) {
+ uint32_t err = ERR_peek_last_error();
+ if (ERR_GET_LIB(err) == ERR_LIB_BN &&
+ ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE) {
+ ERR_clear_error();
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_COMPRESSED_POINT);
+ } else {
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
+ }
+ goto err;
+ }
+
+ if (y_bit != BN_is_odd(y)) {
+ if (BN_is_zero(y)) {
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_COMPRESSION_BIT);
+ goto err;
+ }
+ if (!BN_usub(y, &group->field, y)) {
+ goto err;
+ }
+ }
+ if (y_bit != BN_is_odd(y)) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+
+ if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) {
+ goto err;
+ }
+
+ ret = 1;
+
+err:
+ BN_CTX_end(ctx);
+ BN_CTX_free(new_ctx);
+ return ret;
+}
diff --git a/src/crypto/fipsmodule/ec/p224-64.c b/src/crypto/fipsmodule/ec/p224-64.c
new file mode 100644
index 0000000..ef83b29
--- /dev/null
+++ b/src/crypto/fipsmodule/ec/p224-64.c
@@ -0,0 +1,1164 @@
+/* Copyright (c) 2015, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+// A 64-bit implementation of the NIST P-224 elliptic curve point multiplication
+//
+// Inspired by Daniel J. Bernstein's public domain nistp224 implementation
+// and Adam Langley's public domain 64-bit C implementation of curve25519.
+
+#include <openssl/base.h>
+
+#include <openssl/bn.h>
+#include <openssl/ec.h>
+#include <openssl/err.h>
+#include <openssl/mem.h>
+
+#include <string.h>
+
+#include "internal.h"
+#include "../delocate.h"
+#include "../../internal.h"
+
+
+#if defined(BORINGSSL_HAS_UINT128) && !defined(OPENSSL_SMALL)
+
+// Field elements are represented as a_0 + 2^56*a_1 + 2^112*a_2 + 2^168*a_3
+// using 64-bit coefficients called 'limbs', and sometimes (for multiplication
+// results) as b_0 + 2^56*b_1 + 2^112*b_2 + 2^168*b_3 + 2^224*b_4 + 2^280*b_5 +
+// 2^336*b_6 using 128-bit coefficients called 'widelimbs'. A 4-p224_limb
+// representation is an 'p224_felem'; a 7-p224_widelimb representation is a
+// 'p224_widefelem'. Even within felems, bits of adjacent limbs overlap, and we
+// don't always reduce the representations: we ensure that inputs to each
+// p224_felem multiplication satisfy a_i < 2^60, so outputs satisfy b_i <
+// 4*2^60*2^60, and fit into a 128-bit word without overflow. The coefficients
+// are then again partially reduced to obtain an p224_felem satisfying a_i <
+// 2^57. We only reduce to the unique minimal representation at the end of the
+// computation.
+
+typedef uint64_t p224_limb;
+typedef uint128_t p224_widelimb;
+
+typedef p224_limb p224_felem[4];
+typedef p224_widelimb p224_widefelem[7];
+
+// Precomputed multiples of the standard generator
+// Points are given in coordinates (X, Y, Z) where Z normally is 1
+// (0 for the point at infinity).
+// For each field element, slice a_0 is word 0, etc.
+//
+// The table has 2 * 16 elements, starting with the following:
+// index | bits | point
+// ------+---------+------------------------------
+// 0 | 0 0 0 0 | 0G
+// 1 | 0 0 0 1 | 1G
+// 2 | 0 0 1 0 | 2^56G
+// 3 | 0 0 1 1 | (2^56 + 1)G
+// 4 | 0 1 0 0 | 2^112G
+// 5 | 0 1 0 1 | (2^112 + 1)G
+// 6 | 0 1 1 0 | (2^112 + 2^56)G
+// 7 | 0 1 1 1 | (2^112 + 2^56 + 1)G
+// 8 | 1 0 0 0 | 2^168G
+// 9 | 1 0 0 1 | (2^168 + 1)G
+// 10 | 1 0 1 0 | (2^168 + 2^56)G
+// 11 | 1 0 1 1 | (2^168 + 2^56 + 1)G
+// 12 | 1 1 0 0 | (2^168 + 2^112)G
+// 13 | 1 1 0 1 | (2^168 + 2^112 + 1)G
+// 14 | 1 1 1 0 | (2^168 + 2^112 + 2^56)G
+// 15 | 1 1 1 1 | (2^168 + 2^112 + 2^56 + 1)G
+// followed by a copy of this with each element multiplied by 2^28.
+//
+// The reason for this is so that we can clock bits into four different
+// locations when doing simple scalar multiplies against the base point,
+// and then another four locations using the second 16 elements.
+static const p224_felem g_p224_pre_comp[2][16][3] = {
+ {{{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}},
+ {{0x3280d6115c1d21, 0xc1d356c2112234, 0x7f321390b94a03, 0xb70e0cbd6bb4bf},
+ {0xd5819985007e34, 0x75a05a07476444, 0xfb4c22dfe6cd43, 0xbd376388b5f723},
+ {1, 0, 0, 0}},
+ {{0xfd9675666ebbe9, 0xbca7664d40ce5e, 0x2242df8d8a2a43, 0x1f49bbb0f99bc5},
+ {0x29e0b892dc9c43, 0xece8608436e662, 0xdc858f185310d0, 0x9812dd4eb8d321},
+ {1, 0, 0, 0}},
+ {{0x6d3e678d5d8eb8, 0x559eed1cb362f1, 0x16e9a3bbce8a3f, 0xeedcccd8c2a748},
+ {0xf19f90ed50266d, 0xabf2b4bf65f9df, 0x313865468fafec, 0x5cb379ba910a17},
+ {1, 0, 0, 0}},
+ {{0x0641966cab26e3, 0x91fb2991fab0a0, 0xefec27a4e13a0b, 0x0499aa8a5f8ebe},
+ {0x7510407766af5d, 0x84d929610d5450, 0x81d77aae82f706, 0x6916f6d4338c5b},
+ {1, 0, 0, 0}},
+ {{0xea95ac3b1f15c6, 0x086000905e82d4, 0xdd323ae4d1c8b1, 0x932b56be7685a3},
+ {0x9ef93dea25dbbf, 0x41665960f390f0, 0xfdec76dbe2a8a7, 0x523e80f019062a},
+ {1, 0, 0, 0}},
+ {{0x822fdd26732c73, 0xa01c83531b5d0f, 0x363f37347c1ba4, 0xc391b45c84725c},
+ {0xbbd5e1b2d6ad24, 0xddfbcde19dfaec, 0xc393da7e222a7f, 0x1efb7890ede244},
+ {1, 0, 0, 0}},
+ {{0x4c9e90ca217da1, 0xd11beca79159bb, 0xff8d33c2c98b7c, 0x2610b39409f849},
+ {0x44d1352ac64da0, 0xcdbb7b2c46b4fb, 0x966c079b753c89, 0xfe67e4e820b112},
+ {1, 0, 0, 0}},
+ {{0xe28cae2df5312d, 0xc71b61d16f5c6e, 0x79b7619a3e7c4c, 0x05c73240899b47},
+ {0x9f7f6382c73e3a, 0x18615165c56bda, 0x641fab2116fd56, 0x72855882b08394},
+ {1, 0, 0, 0}},
+ {{0x0469182f161c09, 0x74a98ca8d00fb5, 0xb89da93489a3e0, 0x41c98768fb0c1d},
+ {0xe5ea05fb32da81, 0x3dce9ffbca6855, 0x1cfe2d3fbf59e6, 0x0e5e03408738a7},
+ {1, 0, 0, 0}},
+ {{0xdab22b2333e87f, 0x4430137a5dd2f6, 0xe03ab9f738beb8, 0xcb0c5d0dc34f24},
+ {0x764a7df0c8fda5, 0x185ba5c3fa2044, 0x9281d688bcbe50, 0xc40331df893881},
+ {1, 0, 0, 0}},
+ {{0xb89530796f0f60, 0xade92bd26909a3, 0x1a0c83fb4884da, 0x1765bf22a5a984},
+ {0x772a9ee75db09e, 0x23bc6c67cec16f, 0x4c1edba8b14e2f, 0xe2a215d9611369},
+ {1, 0, 0, 0}},
+ {{0x571e509fb5efb3, 0xade88696410552, 0xc8ae85fada74fe, 0x6c7e4be83bbde3},
+ {0xff9f51160f4652, 0xb47ce2495a6539, 0xa2946c53b582f4, 0x286d2db3ee9a60},
+ {1, 0, 0, 0}},
+ {{0x40bbd5081a44af, 0x0995183b13926c, 0xbcefba6f47f6d0, 0x215619e9cc0057},
+ {0x8bc94d3b0df45e, 0xf11c54a3694f6f, 0x8631b93cdfe8b5, 0xe7e3f4b0982db9},
+ {1, 0, 0, 0}},
+ {{0xb17048ab3e1c7b, 0xac38f36ff8a1d8, 0x1c29819435d2c6, 0xc813132f4c07e9},
+ {0x2891425503b11f, 0x08781030579fea, 0xf5426ba5cc9674, 0x1e28ebf18562bc},
+ {1, 0, 0, 0}},
+ {{0x9f31997cc864eb, 0x06cd91d28b5e4c, 0xff17036691a973, 0xf1aef351497c58},
+ {0xdd1f2d600564ff, 0xdead073b1402db, 0x74a684435bd693, 0xeea7471f962558},
+ {1, 0, 0, 0}}},
+ {{{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}},
+ {{0x9665266dddf554, 0x9613d78b60ef2d, 0xce27a34cdba417, 0xd35ab74d6afc31},
+ {0x85ccdd22deb15e, 0x2137e5783a6aab, 0xa141cffd8c93c6, 0x355a1830e90f2d},
+ {1, 0, 0, 0}},
+ {{0x1a494eadaade65, 0xd6da4da77fe53c, 0xe7992996abec86, 0x65c3553c6090e3},
+ {0xfa610b1fb09346, 0xf1c6540b8a4aaf, 0xc51a13ccd3cbab, 0x02995b1b18c28a},
+ {1, 0, 0, 0}},
+ {{0x7874568e7295ef, 0x86b419fbe38d04, 0xdc0690a7550d9a, 0xd3966a44beac33},
+ {0x2b7280ec29132f, 0xbeaa3b6a032df3, 0xdc7dd88ae41200, 0xd25e2513e3a100},
+ {1, 0, 0, 0}},
+ {{0x924857eb2efafd, 0xac2bce41223190, 0x8edaa1445553fc, 0x825800fd3562d5},
+ {0x8d79148ea96621, 0x23a01c3dd9ed8d, 0xaf8b219f9416b5, 0xd8db0cc277daea},
+ {1, 0, 0, 0}},
+ {{0x76a9c3b1a700f0, 0xe9acd29bc7e691, 0x69212d1a6b0327, 0x6322e97fe154be},
+ {0x469fc5465d62aa, 0x8d41ed18883b05, 0x1f8eae66c52b88, 0xe4fcbe9325be51},
+ {1, 0, 0, 0}},
+ {{0x825fdf583cac16, 0x020b857c7b023a, 0x683c17744b0165, 0x14ffd0a2daf2f1},
+ {0x323b36184218f9, 0x4944ec4e3b47d4, 0xc15b3080841acf, 0x0bced4b01a28bb},
+ {1, 0, 0, 0}},
+ {{0x92ac22230df5c4, 0x52f33b4063eda8, 0xcb3f19870c0c93, 0x40064f2ba65233},
+ {0xfe16f0924f8992, 0x012da25af5b517, 0x1a57bb24f723a6, 0x06f8bc76760def},
+ {1, 0, 0, 0}},
+ {{0x4a7084f7817cb9, 0xbcab0738ee9a78, 0x3ec11e11d9c326, 0xdc0fe90e0f1aae},
+ {0xcf639ea5f98390, 0x5c350aa22ffb74, 0x9afae98a4047b7, 0x956ec2d617fc45},
+ {1, 0, 0, 0}},
+ {{0x4306d648c1be6a, 0x9247cd8bc9a462, 0xf5595e377d2f2e, 0xbd1c3caff1a52e},
+ {0x045e14472409d0, 0x29f3e17078f773, 0x745a602b2d4f7d, 0x191837685cdfbb},
+ {1, 0, 0, 0}},
+ {{0x5b6ee254a8cb79, 0x4953433f5e7026, 0xe21faeb1d1def4, 0xc4c225785c09de},
+ {0x307ce7bba1e518, 0x31b125b1036db8, 0x47e91868839e8f, 0xc765866e33b9f3},
+ {1, 0, 0, 0}},
+ {{0x3bfece24f96906, 0x4794da641e5093, 0xde5df64f95db26, 0x297ecd89714b05},
+ {0x701bd3ebb2c3aa, 0x7073b4f53cb1d5, 0x13c5665658af16, 0x9895089d66fe58},
+ {1, 0, 0, 0}},
+ {{0x0fef05f78c4790, 0x2d773633b05d2e, 0x94229c3a951c94, 0xbbbd70df4911bb},
+ {0xb2c6963d2c1168, 0x105f47a72b0d73, 0x9fdf6111614080, 0x7b7e94b39e67b0},
+ {1, 0, 0, 0}},
+ {{0xad1a7d6efbe2b3, 0xf012482c0da69d, 0x6b3bdf12438345, 0x40d7558d7aa4d9},
+ {0x8a09fffb5c6d3d, 0x9a356e5d9ffd38, 0x5973f15f4f9b1c, 0xdcd5f59f63c3ea},
+ {1, 0, 0, 0}},
+ {{0xacf39f4c5ca7ab, 0x4c8071cc5fd737, 0xc64e3602cd1184, 0x0acd4644c9abba},
+ {0x6c011a36d8bf6e, 0xfecd87ba24e32a, 0x19f6f56574fad8, 0x050b204ced9405},
+ {1, 0, 0, 0}},
+ {{0xed4f1cae7d9a96, 0x5ceef7ad94c40a, 0x778e4a3bf3ef9b, 0x7405783dc3b55e},
+ {0x32477c61b6e8c6, 0xb46a97570f018b, 0x91176d0a7e95d1, 0x3df90fbc4c7d0e},
+ {1, 0, 0, 0}}}};
+
+
+// Helper functions to convert field elements to/from internal representation
+
+static void p224_generic_to_felem(p224_felem out, const EC_FELEM *in) {
+ // |p224_felem|'s minimal representation uses four 56-bit words. |EC_FELEM|
+ // uses four 64-bit words. (The top-most word only has 32 bits.)
+ out[0] = in->words[0] & 0x00ffffffffffffff;
+ out[1] = ((in->words[0] >> 56) | (in->words[1] << 8)) & 0x00ffffffffffffff;
+ out[2] = ((in->words[1] >> 48) | (in->words[2] << 16)) & 0x00ffffffffffffff;
+ out[3] = ((in->words[2] >> 40) | (in->words[3] << 24)) & 0x00ffffffffffffff;
+}
+
+// Requires 0 <= in < 2*p (always call p224_felem_reduce first)
+static void p224_felem_to_generic(EC_FELEM *out, const p224_felem in) {
+ // Reduce to unique minimal representation.
+ static const int64_t two56 = ((p224_limb)1) << 56;
+ // 0 <= in < 2*p, p = 2^224 - 2^96 + 1
+ // if in > p , reduce in = in - 2^224 + 2^96 - 1
+ int64_t tmp[4], a;
+ tmp[0] = in[0];
+ tmp[1] = in[1];
+ tmp[2] = in[2];
+ tmp[3] = in[3];
+ // Case 1: a = 1 iff in >= 2^224
+ a = (in[3] >> 56);
+ tmp[0] -= a;
+ tmp[1] += a << 40;
+ tmp[3] &= 0x00ffffffffffffff;
+ // Case 2: a = 0 iff p <= in < 2^224, i.e., the high 128 bits are all 1 and
+ // the lower part is non-zero
+ a = ((in[3] & in[2] & (in[1] | 0x000000ffffffffff)) + 1) |
+ (((int64_t)(in[0] + (in[1] & 0x000000ffffffffff)) - 1) >> 63);
+ a &= 0x00ffffffffffffff;
+ // turn a into an all-one mask (if a = 0) or an all-zero mask
+ a = (a - 1) >> 63;
+ // subtract 2^224 - 2^96 + 1 if a is all-one
+ tmp[3] &= a ^ 0xffffffffffffffff;
+ tmp[2] &= a ^ 0xffffffffffffffff;
+ tmp[1] &= (a ^ 0xffffffffffffffff) | 0x000000ffffffffff;
+ tmp[0] -= 1 & a;
+
+ // eliminate negative coefficients: if tmp[0] is negative, tmp[1] must
+ // be non-zero, so we only need one step
+ a = tmp[0] >> 63;
+ tmp[0] += two56 & a;
+ tmp[1] -= 1 & a;
+
+ // carry 1 -> 2 -> 3
+ tmp[2] += tmp[1] >> 56;
+ tmp[1] &= 0x00ffffffffffffff;
+
+ tmp[3] += tmp[2] >> 56;
+ tmp[2] &= 0x00ffffffffffffff;
+
+ // Now 0 <= tmp < p
+ p224_felem tmp2;
+ tmp2[0] = tmp[0];
+ tmp2[1] = tmp[1];
+ tmp2[2] = tmp[2];
+ tmp2[3] = tmp[3];
+
+ // |p224_felem|'s minimal representation uses four 56-bit words. |EC_FELEM|
+ // uses four 64-bit words. (The top-most word only has 32 bits.)
+ out->words[0] = tmp2[0] | (tmp2[1] << 56);
+ out->words[1] = (tmp2[1] >> 8) | (tmp2[2] << 48);
+ out->words[2] = (tmp2[2] >> 16) | (tmp2[3] << 40);
+ out->words[3] = tmp2[3] >> 24;
+}
+
+
+// Field operations, using the internal representation of field elements.
+// NB! These operations are specific to our point multiplication and cannot be
+// expected to be correct in general - e.g., multiplication with a large scalar
+// will cause an overflow.
+
+static void p224_felem_assign(p224_felem out, const p224_felem in) {
+ out[0] = in[0];
+ out[1] = in[1];
+ out[2] = in[2];
+ out[3] = in[3];
+}
+
+// Sum two field elements: out += in
+static void p224_felem_sum(p224_felem out, const p224_felem in) {
+ out[0] += in[0];
+ out[1] += in[1];
+ out[2] += in[2];
+ out[3] += in[3];
+}
+
+// Subtract field elements: out -= in
+// Assumes in[i] < 2^57
+static void p224_felem_diff(p224_felem out, const p224_felem in) {
+ static const p224_limb two58p2 =
+ (((p224_limb)1) << 58) + (((p224_limb)1) << 2);
+ static const p224_limb two58m2 =
+ (((p224_limb)1) << 58) - (((p224_limb)1) << 2);
+ static const p224_limb two58m42m2 =
+ (((p224_limb)1) << 58) - (((p224_limb)1) << 42) - (((p224_limb)1) << 2);
+
+ // Add 0 mod 2^224-2^96+1 to ensure out > in
+ out[0] += two58p2;
+ out[1] += two58m42m2;
+ out[2] += two58m2;
+ out[3] += two58m2;
+
+ out[0] -= in[0];
+ out[1] -= in[1];
+ out[2] -= in[2];
+ out[3] -= in[3];
+}
+
+// Subtract in unreduced 128-bit mode: out -= in
+// Assumes in[i] < 2^119
+static void p224_widefelem_diff(p224_widefelem out, const p224_widefelem in) {
+ static const p224_widelimb two120 = ((p224_widelimb)1) << 120;
+ static const p224_widelimb two120m64 =
+ (((p224_widelimb)1) << 120) - (((p224_widelimb)1) << 64);
+ static const p224_widelimb two120m104m64 = (((p224_widelimb)1) << 120) -
+ (((p224_widelimb)1) << 104) -
+ (((p224_widelimb)1) << 64);
+
+ // Add 0 mod 2^224-2^96+1 to ensure out > in
+ out[0] += two120;
+ out[1] += two120m64;
+ out[2] += two120m64;
+ out[3] += two120;
+ out[4] += two120m104m64;
+ out[5] += two120m64;
+ out[6] += two120m64;
+
+ out[0] -= in[0];
+ out[1] -= in[1];
+ out[2] -= in[2];
+ out[3] -= in[3];
+ out[4] -= in[4];
+ out[5] -= in[5];
+ out[6] -= in[6];
+}
+
+// Subtract in mixed mode: out128 -= in64
+// in[i] < 2^63
+static void p224_felem_diff_128_64(p224_widefelem out, const p224_felem in) {
+ static const p224_widelimb two64p8 =
+ (((p224_widelimb)1) << 64) + (((p224_widelimb)1) << 8);
+ static const p224_widelimb two64m8 =
+ (((p224_widelimb)1) << 64) - (((p224_widelimb)1) << 8);
+ static const p224_widelimb two64m48m8 = (((p224_widelimb)1) << 64) -
+ (((p224_widelimb)1) << 48) -
+ (((p224_widelimb)1) << 8);
+
+ // Add 0 mod 2^224-2^96+1 to ensure out > in
+ out[0] += two64p8;
+ out[1] += two64m48m8;
+ out[2] += two64m8;
+ out[3] += two64m8;
+
+ out[0] -= in[0];
+ out[1] -= in[1];
+ out[2] -= in[2];
+ out[3] -= in[3];
+}
+
+// Multiply a field element by a scalar: out = out * scalar
+// The scalars we actually use are small, so results fit without overflow
+static void p224_felem_scalar(p224_felem out, const p224_limb scalar) {
+ out[0] *= scalar;
+ out[1] *= scalar;
+ out[2] *= scalar;
+ out[3] *= scalar;
+}
+
+// Multiply an unreduced field element by a scalar: out = out * scalar
+// The scalars we actually use are small, so results fit without overflow
+static void p224_widefelem_scalar(p224_widefelem out,
+ const p224_widelimb scalar) {
+ out[0] *= scalar;
+ out[1] *= scalar;
+ out[2] *= scalar;
+ out[3] *= scalar;
+ out[4] *= scalar;
+ out[5] *= scalar;
+ out[6] *= scalar;
+}
+
+// Square a field element: out = in^2
+static void p224_felem_square(p224_widefelem out, const p224_felem in) {
+ p224_limb tmp0, tmp1, tmp2;
+ tmp0 = 2 * in[0];
+ tmp1 = 2 * in[1];
+ tmp2 = 2 * in[2];
+ out[0] = ((p224_widelimb)in[0]) * in[0];
+ out[1] = ((p224_widelimb)in[0]) * tmp1;
+ out[2] = ((p224_widelimb)in[0]) * tmp2 + ((p224_widelimb)in[1]) * in[1];
+ out[3] = ((p224_widelimb)in[3]) * tmp0 + ((p224_widelimb)in[1]) * tmp2;
+ out[4] = ((p224_widelimb)in[3]) * tmp1 + ((p224_widelimb)in[2]) * in[2];
+ out[5] = ((p224_widelimb)in[3]) * tmp2;
+ out[6] = ((p224_widelimb)in[3]) * in[3];
+}
+
+// Multiply two field elements: out = in1 * in2
+static void p224_felem_mul(p224_widefelem out, const p224_felem in1,
+ const p224_felem in2) {
+ out[0] = ((p224_widelimb)in1[0]) * in2[0];
+ out[1] = ((p224_widelimb)in1[0]) * in2[1] + ((p224_widelimb)in1[1]) * in2[0];
+ out[2] = ((p224_widelimb)in1[0]) * in2[2] + ((p224_widelimb)in1[1]) * in2[1] +
+ ((p224_widelimb)in1[2]) * in2[0];
+ out[3] = ((p224_widelimb)in1[0]) * in2[3] + ((p224_widelimb)in1[1]) * in2[2] +
+ ((p224_widelimb)in1[2]) * in2[1] + ((p224_widelimb)in1[3]) * in2[0];
+ out[4] = ((p224_widelimb)in1[1]) * in2[3] + ((p224_widelimb)in1[2]) * in2[2] +
+ ((p224_widelimb)in1[3]) * in2[1];
+ out[5] = ((p224_widelimb)in1[2]) * in2[3] + ((p224_widelimb)in1[3]) * in2[2];
+ out[6] = ((p224_widelimb)in1[3]) * in2[3];
+}
+
+// Reduce seven 128-bit coefficients to four 64-bit coefficients.
+// Requires in[i] < 2^126,
+// ensures out[0] < 2^56, out[1] < 2^56, out[2] < 2^56, out[3] <= 2^56 + 2^16
+static void p224_felem_reduce(p224_felem out, const p224_widefelem in) {
+ static const p224_widelimb two127p15 =
+ (((p224_widelimb)1) << 127) + (((p224_widelimb)1) << 15);
+ static const p224_widelimb two127m71 =
+ (((p224_widelimb)1) << 127) - (((p224_widelimb)1) << 71);
+ static const p224_widelimb two127m71m55 = (((p224_widelimb)1) << 127) -
+ (((p224_widelimb)1) << 71) -
+ (((p224_widelimb)1) << 55);
+ p224_widelimb output[5];
+
+ // Add 0 mod 2^224-2^96+1 to ensure all differences are positive
+ output[0] = in[0] + two127p15;
+ output[1] = in[1] + two127m71m55;
+ output[2] = in[2] + two127m71;
+ output[3] = in[3];
+ output[4] = in[4];
+
+ // Eliminate in[4], in[5], in[6]
+ output[4] += in[6] >> 16;
+ output[3] += (in[6] & 0xffff) << 40;
+ output[2] -= in[6];
+
+ output[3] += in[5] >> 16;
+ output[2] += (in[5] & 0xffff) << 40;
+ output[1] -= in[5];
+
+ output[2] += output[4] >> 16;
+ output[1] += (output[4] & 0xffff) << 40;
+ output[0] -= output[4];
+
+ // Carry 2 -> 3 -> 4
+ output[3] += output[2] >> 56;
+ output[2] &= 0x00ffffffffffffff;
+
+ output[4] = output[3] >> 56;
+ output[3] &= 0x00ffffffffffffff;
+
+ // Now output[2] < 2^56, output[3] < 2^56, output[4] < 2^72
+
+ // Eliminate output[4]
+ output[2] += output[4] >> 16;
+ // output[2] < 2^56 + 2^56 = 2^57
+ output[1] += (output[4] & 0xffff) << 40;
+ output[0] -= output[4];
+
+ // Carry 0 -> 1 -> 2 -> 3
+ output[1] += output[0] >> 56;
+ out[0] = output[0] & 0x00ffffffffffffff;
+
+ output[2] += output[1] >> 56;
+ // output[2] < 2^57 + 2^72
+ out[1] = output[1] & 0x00ffffffffffffff;
+ output[3] += output[2] >> 56;
+ // output[3] <= 2^56 + 2^16
+ out[2] = output[2] & 0x00ffffffffffffff;
+
+ // out[0] < 2^56, out[1] < 2^56, out[2] < 2^56,
+ // out[3] <= 2^56 + 2^16 (due to final carry),
+ // so out < 2*p
+ out[3] = output[3];
+}
+
+// Get negative value: out = -in
+// Requires in[i] < 2^63,
+// ensures out[0] < 2^56, out[1] < 2^56, out[2] < 2^56, out[3] <= 2^56 + 2^16
+static void p224_felem_neg(p224_felem out, const p224_felem in) {
+ p224_widefelem tmp = {0};
+ p224_felem_diff_128_64(tmp, in);
+ p224_felem_reduce(out, tmp);
+}
+
+// Zero-check: returns 1 if input is 0, and 0 otherwise. We know that field
+// elements are reduced to in < 2^225, so we only need to check three cases: 0,
+// 2^224 - 2^96 + 1, and 2^225 - 2^97 + 2
+static p224_limb p224_felem_is_zero(const p224_felem in) {
+ p224_limb zero = in[0] | in[1] | in[2] | in[3];
+ zero = (((int64_t)(zero)-1) >> 63) & 1;
+
+ p224_limb two224m96p1 = (in[0] ^ 1) | (in[1] ^ 0x00ffff0000000000) |
+ (in[2] ^ 0x00ffffffffffffff) |
+ (in[3] ^ 0x00ffffffffffffff);
+ two224m96p1 = (((int64_t)(two224m96p1)-1) >> 63) & 1;
+ p224_limb two225m97p2 = (in[0] ^ 2) | (in[1] ^ 0x00fffe0000000000) |
+ (in[2] ^ 0x00ffffffffffffff) |
+ (in[3] ^ 0x01ffffffffffffff);
+ two225m97p2 = (((int64_t)(two225m97p2)-1) >> 63) & 1;
+ return (zero | two224m96p1 | two225m97p2);
+}
+
+// Invert a field element
+// Computation chain copied from djb's code
+static void p224_felem_inv(p224_felem out, const p224_felem in) {
+ p224_felem ftmp, ftmp2, ftmp3, ftmp4;
+ p224_widefelem tmp;
+
+ p224_felem_square(tmp, in);
+ p224_felem_reduce(ftmp, tmp); // 2
+ p224_felem_mul(tmp, in, ftmp);
+ p224_felem_reduce(ftmp, tmp); // 2^2 - 1
+ p224_felem_square(tmp, ftmp);
+ p224_felem_reduce(ftmp, tmp); // 2^3 - 2
+ p224_felem_mul(tmp, in, ftmp);
+ p224_felem_reduce(ftmp, tmp); // 2^3 - 1
+ p224_felem_square(tmp, ftmp);
+ p224_felem_reduce(ftmp2, tmp); // 2^4 - 2
+ p224_felem_square(tmp, ftmp2);
+ p224_felem_reduce(ftmp2, tmp); // 2^5 - 4
+ p224_felem_square(tmp, ftmp2);
+ p224_felem_reduce(ftmp2, tmp); // 2^6 - 8
+ p224_felem_mul(tmp, ftmp2, ftmp);
+ p224_felem_reduce(ftmp, tmp); // 2^6 - 1
+ p224_felem_square(tmp, ftmp);
+ p224_felem_reduce(ftmp2, tmp); // 2^7 - 2
+ for (size_t i = 0; i < 5; ++i) { // 2^12 - 2^6
+ p224_felem_square(tmp, ftmp2);
+ p224_felem_reduce(ftmp2, tmp);
+ }
+ p224_felem_mul(tmp, ftmp2, ftmp);
+ p224_felem_reduce(ftmp2, tmp); // 2^12 - 1
+ p224_felem_square(tmp, ftmp2);
+ p224_felem_reduce(ftmp3, tmp); // 2^13 - 2
+ for (size_t i = 0; i < 11; ++i) { // 2^24 - 2^12
+ p224_felem_square(tmp, ftmp3);
+ p224_felem_reduce(ftmp3, tmp);
+ }
+ p224_felem_mul(tmp, ftmp3, ftmp2);
+ p224_felem_reduce(ftmp2, tmp); // 2^24 - 1
+ p224_felem_square(tmp, ftmp2);
+ p224_felem_reduce(ftmp3, tmp); // 2^25 - 2
+ for (size_t i = 0; i < 23; ++i) { // 2^48 - 2^24
+ p224_felem_square(tmp, ftmp3);
+ p224_felem_reduce(ftmp3, tmp);
+ }
+ p224_felem_mul(tmp, ftmp3, ftmp2);
+ p224_felem_reduce(ftmp3, tmp); // 2^48 - 1
+ p224_felem_square(tmp, ftmp3);
+ p224_felem_reduce(ftmp4, tmp); // 2^49 - 2
+ for (size_t i = 0; i < 47; ++i) { // 2^96 - 2^48
+ p224_felem_square(tmp, ftmp4);
+ p224_felem_reduce(ftmp4, tmp);
+ }
+ p224_felem_mul(tmp, ftmp3, ftmp4);
+ p224_felem_reduce(ftmp3, tmp); // 2^96 - 1
+ p224_felem_square(tmp, ftmp3);
+ p224_felem_reduce(ftmp4, tmp); // 2^97 - 2
+ for (size_t i = 0; i < 23; ++i) { // 2^120 - 2^24
+ p224_felem_square(tmp, ftmp4);
+ p224_felem_reduce(ftmp4, tmp);
+ }
+ p224_felem_mul(tmp, ftmp2, ftmp4);
+ p224_felem_reduce(ftmp2, tmp); // 2^120 - 1
+ for (size_t i = 0; i < 6; ++i) { // 2^126 - 2^6
+ p224_felem_square(tmp, ftmp2);
+ p224_felem_reduce(ftmp2, tmp);
+ }
+ p224_felem_mul(tmp, ftmp2, ftmp);
+ p224_felem_reduce(ftmp, tmp); // 2^126 - 1
+ p224_felem_square(tmp, ftmp);
+ p224_felem_reduce(ftmp, tmp); // 2^127 - 2
+ p224_felem_mul(tmp, ftmp, in);
+ p224_felem_reduce(ftmp, tmp); // 2^127 - 1
+ for (size_t i = 0; i < 97; ++i) { // 2^224 - 2^97
+ p224_felem_square(tmp, ftmp);
+ p224_felem_reduce(ftmp, tmp);
+ }
+ p224_felem_mul(tmp, ftmp, ftmp3);
+ p224_felem_reduce(out, tmp); // 2^224 - 2^96 - 1
+}
+
+// Copy in constant time:
+// if icopy == 1, copy in to out,
+// if icopy == 0, copy out to itself.
+static void p224_copy_conditional(p224_felem out, const p224_felem in,
+ p224_limb icopy) {
+ // icopy is a (64-bit) 0 or 1, so copy is either all-zero or all-one
+ const p224_limb copy = -icopy;
+ for (size_t i = 0; i < 4; ++i) {
+ const p224_limb tmp = copy & (in[i] ^ out[i]);
+ out[i] ^= tmp;
+ }
+}
+
+// ELLIPTIC CURVE POINT OPERATIONS
+//
+// Points are represented in Jacobian projective coordinates:
+// (X, Y, Z) corresponds to the affine point (X/Z^2, Y/Z^3),
+// or to the point at infinity if Z == 0.
+
+// Double an elliptic curve point:
+// (X', Y', Z') = 2 * (X, Y, Z), where
+// X' = (3 * (X - Z^2) * (X + Z^2))^2 - 8 * X * Y^2
+// Y' = 3 * (X - Z^2) * (X + Z^2) * (4 * X * Y^2 - X') - 8 * Y^2
+// Z' = (Y + Z)^2 - Y^2 - Z^2 = 2 * Y * Z
+// Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed,
+// while x_out == y_in is not (maybe this works, but it's not tested).
+static void p224_point_double(p224_felem x_out, p224_felem y_out,
+ p224_felem z_out, const p224_felem x_in,
+ const p224_felem y_in, const p224_felem z_in) {
+ p224_widefelem tmp, tmp2;
+ p224_felem delta, gamma, beta, alpha, ftmp, ftmp2;
+
+ p224_felem_assign(ftmp, x_in);
+ p224_felem_assign(ftmp2, x_in);
+
+ // delta = z^2
+ p224_felem_square(tmp, z_in);
+ p224_felem_reduce(delta, tmp);
+
+ // gamma = y^2
+ p224_felem_square(tmp, y_in);
+ p224_felem_reduce(gamma, tmp);
+
+ // beta = x*gamma
+ p224_felem_mul(tmp, x_in, gamma);
+ p224_felem_reduce(beta, tmp);
+
+ // alpha = 3*(x-delta)*(x+delta)
+ p224_felem_diff(ftmp, delta);
+ // ftmp[i] < 2^57 + 2^58 + 2 < 2^59
+ p224_felem_sum(ftmp2, delta);
+ // ftmp2[i] < 2^57 + 2^57 = 2^58
+ p224_felem_scalar(ftmp2, 3);
+ // ftmp2[i] < 3 * 2^58 < 2^60
+ p224_felem_mul(tmp, ftmp, ftmp2);
+ // tmp[i] < 2^60 * 2^59 * 4 = 2^121
+ p224_felem_reduce(alpha, tmp);
+
+ // x' = alpha^2 - 8*beta
+ p224_felem_square(tmp, alpha);
+ // tmp[i] < 4 * 2^57 * 2^57 = 2^116
+ p224_felem_assign(ftmp, beta);
+ p224_felem_scalar(ftmp, 8);
+ // ftmp[i] < 8 * 2^57 = 2^60
+ p224_felem_diff_128_64(tmp, ftmp);
+ // tmp[i] < 2^116 + 2^64 + 8 < 2^117
+ p224_felem_reduce(x_out, tmp);
+
+ // z' = (y + z)^2 - gamma - delta
+ p224_felem_sum(delta, gamma);
+ // delta[i] < 2^57 + 2^57 = 2^58
+ p224_felem_assign(ftmp, y_in);
+ p224_felem_sum(ftmp, z_in);
+ // ftmp[i] < 2^57 + 2^57 = 2^58
+ p224_felem_square(tmp, ftmp);
+ // tmp[i] < 4 * 2^58 * 2^58 = 2^118
+ p224_felem_diff_128_64(tmp, delta);
+ // tmp[i] < 2^118 + 2^64 + 8 < 2^119
+ p224_felem_reduce(z_out, tmp);
+
+ // y' = alpha*(4*beta - x') - 8*gamma^2
+ p224_felem_scalar(beta, 4);
+ // beta[i] < 4 * 2^57 = 2^59
+ p224_felem_diff(beta, x_out);
+ // beta[i] < 2^59 + 2^58 + 2 < 2^60
+ p224_felem_mul(tmp, alpha, beta);
+ // tmp[i] < 4 * 2^57 * 2^60 = 2^119
+ p224_felem_square(tmp2, gamma);
+ // tmp2[i] < 4 * 2^57 * 2^57 = 2^116
+ p224_widefelem_scalar(tmp2, 8);
+ // tmp2[i] < 8 * 2^116 = 2^119
+ p224_widefelem_diff(tmp, tmp2);
+ // tmp[i] < 2^119 + 2^120 < 2^121
+ p224_felem_reduce(y_out, tmp);
+}
+
+// Add two elliptic curve points:
+// (X_1, Y_1, Z_1) + (X_2, Y_2, Z_2) = (X_3, Y_3, Z_3), where
+// X_3 = (Z_1^3 * Y_2 - Z_2^3 * Y_1)^2 - (Z_1^2 * X_2 - Z_2^2 * X_1)^3 -
+// 2 * Z_2^2 * X_1 * (Z_1^2 * X_2 - Z_2^2 * X_1)^2
+// Y_3 = (Z_1^3 * Y_2 - Z_2^3 * Y_1) * (Z_2^2 * X_1 * (Z_1^2 * X_2 - Z_2^2 *
+// X_1)^2 - X_3) -
+// Z_2^3 * Y_1 * (Z_1^2 * X_2 - Z_2^2 * X_1)^3
+// Z_3 = (Z_1^2 * X_2 - Z_2^2 * X_1) * (Z_1 * Z_2)
+//
+// This runs faster if 'mixed' is set, which requires Z_2 = 1 or Z_2 = 0.
+
+// This function is not entirely constant-time: it includes a branch for
+// checking whether the two input points are equal, (while not equal to the
+// point at infinity). This case never happens during single point
+// multiplication, so there is no timing leak for ECDH or ECDSA signing.
+static void p224_point_add(p224_felem x3, p224_felem y3, p224_felem z3,
+ const p224_felem x1, const p224_felem y1,
+ const p224_felem z1, const int mixed,
+ const p224_felem x2, const p224_felem y2,
+ const p224_felem z2) {
+ p224_felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, x_out, y_out, z_out;
+ p224_widefelem tmp, tmp2;
+ p224_limb z1_is_zero, z2_is_zero, x_equal, y_equal;
+
+ if (!mixed) {
+ // ftmp2 = z2^2
+ p224_felem_square(tmp, z2);
+ p224_felem_reduce(ftmp2, tmp);
+
+ // ftmp4 = z2^3
+ p224_felem_mul(tmp, ftmp2, z2);
+ p224_felem_reduce(ftmp4, tmp);
+
+ // ftmp4 = z2^3*y1
+ p224_felem_mul(tmp2, ftmp4, y1);
+ p224_felem_reduce(ftmp4, tmp2);
+
+ // ftmp2 = z2^2*x1
+ p224_felem_mul(tmp2, ftmp2, x1);
+ p224_felem_reduce(ftmp2, tmp2);
+ } else {
+ // We'll assume z2 = 1 (special case z2 = 0 is handled later)
+
+ // ftmp4 = z2^3*y1
+ p224_felem_assign(ftmp4, y1);
+
+ // ftmp2 = z2^2*x1
+ p224_felem_assign(ftmp2, x1);
+ }
+
+ // ftmp = z1^2
+ p224_felem_square(tmp, z1);
+ p224_felem_reduce(ftmp, tmp);
+
+ // ftmp3 = z1^3
+ p224_felem_mul(tmp, ftmp, z1);
+ p224_felem_reduce(ftmp3, tmp);
+
+ // tmp = z1^3*y2
+ p224_felem_mul(tmp, ftmp3, y2);
+ // tmp[i] < 4 * 2^57 * 2^57 = 2^116
+
+ // ftmp3 = z1^3*y2 - z2^3*y1
+ p224_felem_diff_128_64(tmp, ftmp4);
+ // tmp[i] < 2^116 + 2^64 + 8 < 2^117
+ p224_felem_reduce(ftmp3, tmp);
+
+ // tmp = z1^2*x2
+ p224_felem_mul(tmp, ftmp, x2);
+ // tmp[i] < 4 * 2^57 * 2^57 = 2^116
+
+ // ftmp = z1^2*x2 - z2^2*x1
+ p224_felem_diff_128_64(tmp, ftmp2);
+ // tmp[i] < 2^116 + 2^64 + 8 < 2^117
+ p224_felem_reduce(ftmp, tmp);
+
+ // the formulae are incorrect if the points are equal
+ // so we check for this and do doubling if this happens
+ x_equal = p224_felem_is_zero(ftmp);
+ y_equal = p224_felem_is_zero(ftmp3);
+ z1_is_zero = p224_felem_is_zero(z1);
+ z2_is_zero = p224_felem_is_zero(z2);
+ // In affine coordinates, (X_1, Y_1) == (X_2, Y_2)
+ p224_limb is_nontrivial_double =
+ x_equal & y_equal & (1 - z1_is_zero) & (1 - z2_is_zero);
+ if (is_nontrivial_double) {
+ p224_point_double(x3, y3, z3, x1, y1, z1);
+ return;
+ }
+
+ // ftmp5 = z1*z2
+ if (!mixed) {
+ p224_felem_mul(tmp, z1, z2);
+ p224_felem_reduce(ftmp5, tmp);
+ } else {
+ // special case z2 = 0 is handled later
+ p224_felem_assign(ftmp5, z1);
+ }
+
+ // z_out = (z1^2*x2 - z2^2*x1)*(z1*z2)
+ p224_felem_mul(tmp, ftmp, ftmp5);
+ p224_felem_reduce(z_out, tmp);
+
+ // ftmp = (z1^2*x2 - z2^2*x1)^2
+ p224_felem_assign(ftmp5, ftmp);
+ p224_felem_square(tmp, ftmp);
+ p224_felem_reduce(ftmp, tmp);
+
+ // ftmp5 = (z1^2*x2 - z2^2*x1)^3
+ p224_felem_mul(tmp, ftmp, ftmp5);
+ p224_felem_reduce(ftmp5, tmp);
+
+ // ftmp2 = z2^2*x1*(z1^2*x2 - z2^2*x1)^2
+ p224_felem_mul(tmp, ftmp2, ftmp);
+ p224_felem_reduce(ftmp2, tmp);
+
+ // tmp = z2^3*y1*(z1^2*x2 - z2^2*x1)^3
+ p224_felem_mul(tmp, ftmp4, ftmp5);
+ // tmp[i] < 4 * 2^57 * 2^57 = 2^116
+
+ // tmp2 = (z1^3*y2 - z2^3*y1)^2
+ p224_felem_square(tmp2, ftmp3);
+ // tmp2[i] < 4 * 2^57 * 2^57 < 2^116
+
+ // tmp2 = (z1^3*y2 - z2^3*y1)^2 - (z1^2*x2 - z2^2*x1)^3
+ p224_felem_diff_128_64(tmp2, ftmp5);
+ // tmp2[i] < 2^116 + 2^64 + 8 < 2^117
+
+ // ftmp5 = 2*z2^2*x1*(z1^2*x2 - z2^2*x1)^2
+ p224_felem_assign(ftmp5, ftmp2);
+ p224_felem_scalar(ftmp5, 2);
+ // ftmp5[i] < 2 * 2^57 = 2^58
+
+ /* x_out = (z1^3*y2 - z2^3*y1)^2 - (z1^2*x2 - z2^2*x1)^3 -
+ 2*z2^2*x1*(z1^2*x2 - z2^2*x1)^2 */
+ p224_felem_diff_128_64(tmp2, ftmp5);
+ // tmp2[i] < 2^117 + 2^64 + 8 < 2^118
+ p224_felem_reduce(x_out, tmp2);
+
+ // ftmp2 = z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out
+ p224_felem_diff(ftmp2, x_out);
+ // ftmp2[i] < 2^57 + 2^58 + 2 < 2^59
+
+ // tmp2 = (z1^3*y2 - z2^3*y1)*(z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out)
+ p224_felem_mul(tmp2, ftmp3, ftmp2);
+ // tmp2[i] < 4 * 2^57 * 2^59 = 2^118
+
+ /* y_out = (z1^3*y2 - z2^3*y1)*(z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out) -
+ z2^3*y1*(z1^2*x2 - z2^2*x1)^3 */
+ p224_widefelem_diff(tmp2, tmp);
+ // tmp2[i] < 2^118 + 2^120 < 2^121
+ p224_felem_reduce(y_out, tmp2);
+
+ // the result (x_out, y_out, z_out) is incorrect if one of the inputs is
+ // the point at infinity, so we need to check for this separately
+
+ // if point 1 is at infinity, copy point 2 to output, and vice versa
+ p224_copy_conditional(x_out, x2, z1_is_zero);
+ p224_copy_conditional(x_out, x1, z2_is_zero);
+ p224_copy_conditional(y_out, y2, z1_is_zero);
+ p224_copy_conditional(y_out, y1, z2_is_zero);
+ p224_copy_conditional(z_out, z2, z1_is_zero);
+ p224_copy_conditional(z_out, z1, z2_is_zero);
+ p224_felem_assign(x3, x_out);
+ p224_felem_assign(y3, y_out);
+ p224_felem_assign(z3, z_out);
+}
+
+// p224_select_point selects the |idx|th point from a precomputation table and
+// copies it to out.
+static void p224_select_point(const uint64_t idx, size_t size,
+ const p224_felem pre_comp[/*size*/][3],
+ p224_felem out[3]) {
+ p224_limb *outlimbs = &out[0][0];
+ OPENSSL_memset(outlimbs, 0, 3 * sizeof(p224_felem));
+
+ for (size_t i = 0; i < size; i++) {
+ const p224_limb *inlimbs = &pre_comp[i][0][0];
+ uint64_t mask = i ^ idx;
+ mask |= mask >> 4;
+ mask |= mask >> 2;
+ mask |= mask >> 1;
+ mask &= 1;
+ mask--;
+ for (size_t j = 0; j < 4 * 3; j++) {
+ outlimbs[j] |= inlimbs[j] & mask;
+ }
+ }
+}
+
+// p224_get_bit returns the |i|th bit in |in|.
+static crypto_word_t p224_get_bit(const EC_SCALAR *in, size_t i) {
+ if (i >= 224) {
+ return 0;
+ }
+ static_assert(sizeof(in->words[0]) == 8, "BN_ULONG is not 64-bit");
+ return (in->words[i >> 6] >> (i & 63)) & 1;
+}
+
+// Takes the Jacobian coordinates (X, Y, Z) of a point and returns
+// (X', Y') = (X/Z^2, Y/Z^3)
+static int ec_GFp_nistp224_point_get_affine_coordinates(
+ const EC_GROUP *group, const EC_JACOBIAN *point, EC_FELEM *x,
+ EC_FELEM *y) {
+ if (ec_GFp_simple_is_at_infinity(group, point)) {
+ OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY);
+ return 0;
+ }
+
+ p224_felem z1, z2;
+ p224_widefelem tmp;
+ p224_generic_to_felem(z1, &point->Z);
+ p224_felem_inv(z2, z1);
+ p224_felem_square(tmp, z2);
+ p224_felem_reduce(z1, tmp);
+
+ if (x != NULL) {
+ p224_felem x_in, x_out;
+ p224_generic_to_felem(x_in, &point->X);
+ p224_felem_mul(tmp, x_in, z1);
+ p224_felem_reduce(x_out, tmp);
+ p224_felem_to_generic(x, x_out);
+ }
+
+ if (y != NULL) {
+ p224_felem y_in, y_out;
+ p224_generic_to_felem(y_in, &point->Y);
+ p224_felem_mul(tmp, z1, z2);
+ p224_felem_reduce(z1, tmp);
+ p224_felem_mul(tmp, y_in, z1);
+ p224_felem_reduce(y_out, tmp);
+ p224_felem_to_generic(y, y_out);
+ }
+
+ return 1;
+}
+
+static void ec_GFp_nistp224_add(const EC_GROUP *group, EC_JACOBIAN *r,
+ const EC_JACOBIAN *a, const EC_JACOBIAN *b) {
+ p224_felem x1, y1, z1, x2, y2, z2;
+ p224_generic_to_felem(x1, &a->X);
+ p224_generic_to_felem(y1, &a->Y);
+ p224_generic_to_felem(z1, &a->Z);
+ p224_generic_to_felem(x2, &b->X);
+ p224_generic_to_felem(y2, &b->Y);
+ p224_generic_to_felem(z2, &b->Z);
+ p224_point_add(x1, y1, z1, x1, y1, z1, 0 /* both Jacobian */, x2, y2, z2);
+ // The outputs are already reduced, but still need to be contracted.
+ p224_felem_to_generic(&r->X, x1);
+ p224_felem_to_generic(&r->Y, y1);
+ p224_felem_to_generic(&r->Z, z1);
+}
+
+static void ec_GFp_nistp224_dbl(const EC_GROUP *group, EC_JACOBIAN *r,
+ const EC_JACOBIAN *a) {
+ p224_felem x, y, z;
+ p224_generic_to_felem(x, &a->X);
+ p224_generic_to_felem(y, &a->Y);
+ p224_generic_to_felem(z, &a->Z);
+ p224_point_double(x, y, z, x, y, z);
+ // The outputs are already reduced, but still need to be contracted.
+ p224_felem_to_generic(&r->X, x);
+ p224_felem_to_generic(&r->Y, y);
+ p224_felem_to_generic(&r->Z, z);
+}
+
+static void ec_GFp_nistp224_make_precomp(p224_felem out[17][3],
+ const EC_JACOBIAN *p) {
+ OPENSSL_memset(out[0], 0, sizeof(p224_felem) * 3);
+
+ p224_generic_to_felem(out[1][0], &p->X);
+ p224_generic_to_felem(out[1][1], &p->Y);
+ p224_generic_to_felem(out[1][2], &p->Z);
+
+ for (size_t j = 2; j <= 16; ++j) {
+ if (j & 1) {
+ p224_point_add(out[j][0], out[j][1], out[j][2], out[1][0], out[1][1],
+ out[1][2], 0, out[j - 1][0], out[j - 1][1], out[j - 1][2]);
+ } else {
+ p224_point_double(out[j][0], out[j][1], out[j][2], out[j / 2][0],
+ out[j / 2][1], out[j / 2][2]);
+ }
+ }
+}
+
+static void ec_GFp_nistp224_point_mul(const EC_GROUP *group, EC_JACOBIAN *r,
+ const EC_JACOBIAN *p,
+ const EC_SCALAR *scalar) {
+ p224_felem p_pre_comp[17][3];
+ ec_GFp_nistp224_make_precomp(p_pre_comp, p);
+
+ // Set nq to the point at infinity.
+ p224_felem nq[3], tmp[4];
+ OPENSSL_memset(nq, 0, 3 * sizeof(p224_felem));
+
+ int skip = 1; // Save two point operations in the first round.
+ for (size_t i = 220; i < 221; i--) {
+ if (!skip) {
+ p224_point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]);
+ }
+
+ // Add every 5 doublings.
+ if (i % 5 == 0) {
+ crypto_word_t bits = p224_get_bit(scalar, i + 4) << 5;
+ bits |= p224_get_bit(scalar, i + 3) << 4;
+ bits |= p224_get_bit(scalar, i + 2) << 3;
+ bits |= p224_get_bit(scalar, i + 1) << 2;
+ bits |= p224_get_bit(scalar, i) << 1;
+ bits |= p224_get_bit(scalar, i - 1);
+ crypto_word_t sign, digit;
+ ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
+
+ // Select the point to add or subtract.
+ p224_select_point(digit, 17, (const p224_felem(*)[3])p_pre_comp, tmp);
+ p224_felem_neg(tmp[3], tmp[1]); // (X, -Y, Z) is the negative point
+ p224_copy_conditional(tmp[1], tmp[3], sign);
+
+ if (!skip) {
+ p224_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 0 /* mixed */,
+ tmp[0], tmp[1], tmp[2]);
+ } else {
+ OPENSSL_memcpy(nq, tmp, 3 * sizeof(p224_felem));
+ skip = 0;
+ }
+ }
+ }
+
+ // Reduce the output to its unique minimal representation.
+ p224_felem_to_generic(&r->X, nq[0]);
+ p224_felem_to_generic(&r->Y, nq[1]);
+ p224_felem_to_generic(&r->Z, nq[2]);
+}
+
+static void ec_GFp_nistp224_point_mul_base(const EC_GROUP *group,
+ EC_JACOBIAN *r,
+ const EC_SCALAR *scalar) {
+ // Set nq to the point at infinity.
+ p224_felem nq[3], tmp[3];
+ OPENSSL_memset(nq, 0, 3 * sizeof(p224_felem));
+
+ int skip = 1; // Save two point operations in the first round.
+ for (size_t i = 27; i < 28; i--) {
+ // double
+ if (!skip) {
+ p224_point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]);
+ }
+
+ // First, look 28 bits upwards.
+ crypto_word_t bits = p224_get_bit(scalar, i + 196) << 3;
+ bits |= p224_get_bit(scalar, i + 140) << 2;
+ bits |= p224_get_bit(scalar, i + 84) << 1;
+ bits |= p224_get_bit(scalar, i + 28);
+ // Select the point to add, in constant time.
+ p224_select_point(bits, 16, g_p224_pre_comp[1], tmp);
+
+ if (!skip) {
+ p224_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */,
+ tmp[0], tmp[1], tmp[2]);
+ } else {
+ OPENSSL_memcpy(nq, tmp, 3 * sizeof(p224_felem));
+ skip = 0;
+ }
+
+ // Second, look at the current position/
+ bits = p224_get_bit(scalar, i + 168) << 3;
+ bits |= p224_get_bit(scalar, i + 112) << 2;
+ bits |= p224_get_bit(scalar, i + 56) << 1;
+ bits |= p224_get_bit(scalar, i);
+ // Select the point to add, in constant time.
+ p224_select_point(bits, 16, g_p224_pre_comp[0], tmp);
+ p224_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */,
+ tmp[0], tmp[1], tmp[2]);
+ }
+
+ // Reduce the output to its unique minimal representation.
+ p224_felem_to_generic(&r->X, nq[0]);
+ p224_felem_to_generic(&r->Y, nq[1]);
+ p224_felem_to_generic(&r->Z, nq[2]);
+}
+
+static void ec_GFp_nistp224_point_mul_public(const EC_GROUP *group,
+ EC_JACOBIAN *r,
+ const EC_SCALAR *g_scalar,
+ const EC_JACOBIAN *p,
+ const EC_SCALAR *p_scalar) {
+ // TODO(davidben): If P-224 ECDSA verify performance ever matters, using
+ // |ec_compute_wNAF| for |p_scalar| would likely be an easy improvement.
+ p224_felem p_pre_comp[17][3];
+ ec_GFp_nistp224_make_precomp(p_pre_comp, p);
+
+ // Set nq to the point at infinity.
+ p224_felem nq[3], tmp[3];
+ OPENSSL_memset(nq, 0, 3 * sizeof(p224_felem));
+
+ // Loop over both scalars msb-to-lsb, interleaving additions of multiples of
+ // the generator (two in each of the last 28 rounds) and additions of p (every
+ // 5th round).
+ int skip = 1; // Save two point operations in the first round.
+ for (size_t i = 220; i < 221; i--) {
+ if (!skip) {
+ p224_point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]);
+ }
+
+ // Add multiples of the generator.
+ if (i <= 27) {
+ // First, look 28 bits upwards.
+ crypto_word_t bits = p224_get_bit(g_scalar, i + 196) << 3;
+ bits |= p224_get_bit(g_scalar, i + 140) << 2;
+ bits |= p224_get_bit(g_scalar, i + 84) << 1;
+ bits |= p224_get_bit(g_scalar, i + 28);
+
+ size_t index = (size_t)bits;
+ p224_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */,
+ g_p224_pre_comp[1][index][0], g_p224_pre_comp[1][index][1],
+ g_p224_pre_comp[1][index][2]);
+ assert(!skip);
+
+ // Second, look at the current position.
+ bits = p224_get_bit(g_scalar, i + 168) << 3;
+ bits |= p224_get_bit(g_scalar, i + 112) << 2;
+ bits |= p224_get_bit(g_scalar, i + 56) << 1;
+ bits |= p224_get_bit(g_scalar, i);
+ index = (size_t)bits;
+ p224_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */,
+ g_p224_pre_comp[0][index][0], g_p224_pre_comp[0][index][1],
+ g_p224_pre_comp[0][index][2]);
+ }
+
+ // Incorporate |p_scalar| every 5 doublings.
+ if (i % 5 == 0) {
+ crypto_word_t bits = p224_get_bit(p_scalar, i + 4) << 5;
+ bits |= p224_get_bit(p_scalar, i + 3) << 4;
+ bits |= p224_get_bit(p_scalar, i + 2) << 3;
+ bits |= p224_get_bit(p_scalar, i + 1) << 2;
+ bits |= p224_get_bit(p_scalar, i) << 1;
+ bits |= p224_get_bit(p_scalar, i - 1);
+ crypto_word_t sign, digit;
+ ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
+
+ // Select the point to add or subtract.
+ OPENSSL_memcpy(tmp, p_pre_comp[digit], 3 * sizeof(p224_felem));
+ if (sign) {
+ p224_felem_neg(tmp[1], tmp[1]); // (X, -Y, Z) is the negative point
+ }
+
+ if (!skip) {
+ p224_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 0 /* mixed */,
+ tmp[0], tmp[1], tmp[2]);
+ } else {
+ OPENSSL_memcpy(nq, tmp, 3 * sizeof(p224_felem));
+ skip = 0;
+ }
+ }
+ }
+
+ // Reduce the output to its unique minimal representation.
+ p224_felem_to_generic(&r->X, nq[0]);
+ p224_felem_to_generic(&r->Y, nq[1]);
+ p224_felem_to_generic(&r->Z, nq[2]);
+}
+
+static void ec_GFp_nistp224_felem_mul(const EC_GROUP *group, EC_FELEM *r,
+ const EC_FELEM *a, const EC_FELEM *b) {
+ p224_felem felem1, felem2;
+ p224_widefelem wide;
+ p224_generic_to_felem(felem1, a);
+ p224_generic_to_felem(felem2, b);
+ p224_felem_mul(wide, felem1, felem2);
+ p224_felem_reduce(felem1, wide);
+ p224_felem_to_generic(r, felem1);
+}
+
+static void ec_GFp_nistp224_felem_sqr(const EC_GROUP *group, EC_FELEM *r,
+ const EC_FELEM *a) {
+ p224_felem felem;
+ p224_generic_to_felem(felem, a);
+ p224_widefelem wide;
+ p224_felem_square(wide, felem);
+ p224_felem_reduce(felem, wide);
+ p224_felem_to_generic(r, felem);
+}
+
+DEFINE_METHOD_FUNCTION(EC_METHOD, EC_GFp_nistp224_method) {
+ out->group_init = ec_GFp_simple_group_init;
+ out->group_finish = ec_GFp_simple_group_finish;
+ out->group_set_curve = ec_GFp_simple_group_set_curve;
+ out->point_get_affine_coordinates =
+ ec_GFp_nistp224_point_get_affine_coordinates;
+ out->add = ec_GFp_nistp224_add;
+ out->dbl = ec_GFp_nistp224_dbl;
+ out->mul = ec_GFp_nistp224_point_mul;
+ out->mul_base = ec_GFp_nistp224_point_mul_base;
+ out->mul_public = ec_GFp_nistp224_point_mul_public;
+ out->felem_mul = ec_GFp_nistp224_felem_mul;
+ out->felem_sqr = ec_GFp_nistp224_felem_sqr;
+ out->felem_to_bytes = ec_GFp_simple_felem_to_bytes;
+ out->felem_from_bytes = ec_GFp_simple_felem_from_bytes;
+ out->scalar_inv0_montgomery = ec_simple_scalar_inv0_montgomery;
+ out->scalar_to_montgomery_inv_vartime =
+ ec_simple_scalar_to_montgomery_inv_vartime;
+ out->cmp_x_coordinate = ec_GFp_simple_cmp_x_coordinate;
+}
+
+#endif // BORINGSSL_HAS_UINT128 && !SMALL
diff --git a/src/crypto/fipsmodule/ec/p256-nistz-table.h b/src/crypto/fipsmodule/ec/p256-nistz-table.h
new file mode 100644
index 0000000..b81480b
--- /dev/null
+++ b/src/crypto/fipsmodule/ec/p256-nistz-table.h
@@ -0,0 +1,9497 @@
+/*
+ * Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright (c) 2015, Intel Inc.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+// This is the precomputed constant time access table for the code in
+// p256-nistz.c, for the default generator. The table consists of 37
+// subtables, each subtable contains 64 affine points. The affine points are
+// encoded as eight uint64's, four for the x coordinate and four for the y.
+// Both values are in little-endian order. There are 37 tables because a
+// signed, 6-bit wNAF form of the scalar is used and ceil(256/(6 + 1)) = 37.
+// Within each table there are 64 values because the 6-bit wNAF value can take
+// 64 values, ignoring the sign bit, which is implemented by performing a
+// negation of the affine point when required. We would like to align it to 2MB
+// in order to increase the chances of using a large page but that appears to
+// lead to invalid ELF files being produced.
+
+// This file is generated by make_tables.go.
+
+static const alignas(4096) PRECOMP256_ROW ecp_nistz256_precomputed[37] = {
+ {{{TOBN(0x79e730d4, 0x18a9143c), TOBN(0x75ba95fc, 0x5fedb601),
+ TOBN(0x79fb732b, 0x77622510), TOBN(0x18905f76, 0xa53755c6)},
+ {TOBN(0xddf25357, 0xce95560a), TOBN(0x8b4ab8e4, 0xba19e45c),
+ TOBN(0xd2e88688, 0xdd21f325), TOBN(0x8571ff18, 0x25885d85)}},
+ {{TOBN(0x850046d4, 0x10ddd64d), TOBN(0xaa6ae3c1, 0xa433827d),
+ TOBN(0x73220503, 0x8d1490d9), TOBN(0xf6bb32e4, 0x3dcf3a3b)},
+ {TOBN(0x2f3648d3, 0x61bee1a5), TOBN(0x152cd7cb, 0xeb236ff8),
+ TOBN(0x19a8fb0e, 0x92042dbe), TOBN(0x78c57751, 0x0a5b8a3b)}},
+ {{TOBN(0xffac3f90, 0x4eebc127), TOBN(0xb027f84a, 0x087d81fb),
+ TOBN(0x66ad77dd, 0x87cbbc98), TOBN(0x26936a3f, 0xb6ff747e)},
+ {TOBN(0xb04c5c1f, 0xc983a7eb), TOBN(0x583e47ad, 0x0861fe1a),
+ TOBN(0x78820831, 0x1a2ee98e), TOBN(0xd5f06a29, 0xe587cc07)}},
+ {{TOBN(0x74b0b50d, 0x46918dcc), TOBN(0x4650a6ed, 0xc623c173),
+ TOBN(0x0cdaacac, 0xe8100af2), TOBN(0x577362f5, 0x41b0176b)},
+ {TOBN(0x2d96f24c, 0xe4cbaba6), TOBN(0x17628471, 0xfad6f447),
+ TOBN(0x6b6c36de, 0xe5ddd22e), TOBN(0x84b14c39, 0x4c5ab863)}},
+ {{TOBN(0xbe1b8aae, 0xc45c61f5), TOBN(0x90ec649a, 0x94b9537d),
+ TOBN(0x941cb5aa, 0xd076c20c), TOBN(0xc9079605, 0x890523c8)},
+ {TOBN(0xeb309b4a, 0xe7ba4f10), TOBN(0x73c568ef, 0xe5eb882b),
+ TOBN(0x3540a987, 0x7e7a1f68), TOBN(0x73a076bb, 0x2dd1e916)}},
+ {{TOBN(0x40394737, 0x3e77664a), TOBN(0x55ae744f, 0x346cee3e),
+ TOBN(0xd50a961a, 0x5b17a3ad), TOBN(0x13074b59, 0x54213673)},
+ {TOBN(0x93d36220, 0xd377e44b), TOBN(0x299c2b53, 0xadff14b5),
+ TOBN(0xf424d44c, 0xef639f11), TOBN(0xa4c9916d, 0x4a07f75f)}},
+ {{TOBN(0x0746354e, 0xa0173b4f), TOBN(0x2bd20213, 0xd23c00f7),
+ TOBN(0xf43eaab5, 0x0c23bb08), TOBN(0x13ba5119, 0xc3123e03)},
+ {TOBN(0x2847d030, 0x3f5b9d4d), TOBN(0x6742f2f2, 0x5da67bdd),
+ TOBN(0xef933bdc, 0x77c94195), TOBN(0xeaedd915, 0x6e240867)}},
+ {{TOBN(0x27f14cd1, 0x9499a78f), TOBN(0x462ab5c5, 0x6f9b3455),
+ TOBN(0x8f90f02a, 0xf02cfc6b), TOBN(0xb763891e, 0xb265230d)},
+ {TOBN(0xf59da3a9, 0x532d4977), TOBN(0x21e3327d, 0xcf9eba15),
+ TOBN(0x123c7b84, 0xbe60bbf0), TOBN(0x56ec12f2, 0x7706df76)}},
+ {{TOBN(0x75c96e8f, 0x264e20e8), TOBN(0xabe6bfed, 0x59a7a841),
+ TOBN(0x2cc09c04, 0x44c8eb00), TOBN(0xe05b3080, 0xf0c4e16b)},
+ {TOBN(0x1eb7777a, 0xa45f3314), TOBN(0x56af7bed, 0xce5d45e3),
+ TOBN(0x2b6e019a, 0x88b12f1a), TOBN(0x086659cd, 0xfd835f9b)}},
+ {{TOBN(0x2c18dbd1, 0x9dc21ec8), TOBN(0x98f9868a, 0x0fcf8139),
+ TOBN(0x737d2cd6, 0x48250b49), TOBN(0xcc61c947, 0x24b3428f)},
+ {TOBN(0x0c2b4078, 0x80dd9e76), TOBN(0xc43a8991, 0x383fbe08),
+ TOBN(0x5f7d2d65, 0x779be5d2), TOBN(0x78719a54, 0xeb3b4ab5)}},
+ {{TOBN(0xea7d260a, 0x6245e404), TOBN(0x9de40795, 0x6e7fdfe0),
+ TOBN(0x1ff3a415, 0x8dac1ab5), TOBN(0x3e7090f1, 0x649c9073)},
+ {TOBN(0x1a768561, 0x2b944e88), TOBN(0x250f939e, 0xe57f61c8),
+ TOBN(0x0c0daa89, 0x1ead643d), TOBN(0x68930023, 0xe125b88e)}},
+ {{TOBN(0x04b71aa7, 0xd2697768), TOBN(0xabdedef5, 0xca345a33),
+ TOBN(0x2409d29d, 0xee37385e), TOBN(0x4ee1df77, 0xcb83e156)},
+ {TOBN(0x0cac12d9, 0x1cbb5b43), TOBN(0x170ed2f6, 0xca895637),
+ TOBN(0x28228cfa, 0x8ade6d66), TOBN(0x7ff57c95, 0x53238aca)}},
+ {{TOBN(0xccc42563, 0x4b2ed709), TOBN(0x0e356769, 0x856fd30d),
+ TOBN(0xbcbcd43f, 0x559e9811), TOBN(0x738477ac, 0x5395b759)},
+ {TOBN(0x35752b90, 0xc00ee17f), TOBN(0x68748390, 0x742ed2e3),
+ TOBN(0x7cd06422, 0xbd1f5bc1), TOBN(0xfbc08769, 0xc9e7b797)}},
+ {{TOBN(0xa242a35b, 0xb0cf664a), TOBN(0x126e48f7, 0x7f9707e3),
+ TOBN(0x1717bf54, 0xc6832660), TOBN(0xfaae7332, 0xfd12c72e)},
+ {TOBN(0x27b52db7, 0x995d586b), TOBN(0xbe29569e, 0x832237c2),
+ TOBN(0xe8e4193e, 0x2a65e7db), TOBN(0x152706dc, 0x2eaa1bbb)}},
+ {{TOBN(0x72bcd8b7, 0xbc60055b), TOBN(0x03cc23ee, 0x56e27e4b),
+ TOBN(0xee337424, 0xe4819370), TOBN(0xe2aa0e43, 0x0ad3da09)},
+ {TOBN(0x40b8524f, 0x6383c45d), TOBN(0xd7663554, 0x42a41b25),
+ TOBN(0x64efa6de, 0x778a4797), TOBN(0x2042170a, 0x7079adf4)}},
+ {{TOBN(0x808b0b65, 0x0bc6fb80), TOBN(0x5882e075, 0x3ffe2e6b),
+ TOBN(0xd5ef2f7c, 0x2c83f549), TOBN(0x54d63c80, 0x9103b723)},
+ {TOBN(0xf2f11bd6, 0x52a23f9b), TOBN(0x3670c319, 0x4b0b6587),
+ TOBN(0x55c4623b, 0xb1580e9e), TOBN(0x64edf7b2, 0x01efe220)}},
+ {{TOBN(0x97091dcb, 0xd53c5c9d), TOBN(0xf17624b6, 0xac0a177b),
+ TOBN(0xb0f13975, 0x2cfe2dff), TOBN(0xc1a35c0a, 0x6c7a574e)},
+ {TOBN(0x227d3146, 0x93e79987), TOBN(0x0575bf30, 0xe89cb80e),
+ TOBN(0x2f4e247f, 0x0d1883bb), TOBN(0xebd51226, 0x3274c3d0)}},
+ {{TOBN(0x5f3e51c8, 0x56ada97a), TOBN(0x4afc964d, 0x8f8b403e),
+ TOBN(0xa6f247ab, 0x412e2979), TOBN(0x675abd1b, 0x6f80ebda)},
+ {TOBN(0x66a2bd72, 0x5e485a1d), TOBN(0x4b2a5caf, 0x8f4f0b3c),
+ TOBN(0x2626927f, 0x1b847bba), TOBN(0x6c6fc7d9, 0x0502394d)}},
+ {{TOBN(0xfea912ba, 0xa5659ae8), TOBN(0x68363aba, 0x25e1a16e),
+ TOBN(0xb8842277, 0x752c41ac), TOBN(0xfe545c28, 0x2897c3fc)},
+ {TOBN(0x2d36e9e7, 0xdc4c696b), TOBN(0x5806244a, 0xfba977c5),
+ TOBN(0x85665e9b, 0xe39508c1), TOBN(0xf720ee25, 0x6d12597b)}},
+ {{TOBN(0x8a979129, 0xd2337a31), TOBN(0x5916868f, 0x0f862bdc),
+ TOBN(0x048099d9, 0x5dd283ba), TOBN(0xe2d1eeb6, 0xfe5bfb4e)},
+ {TOBN(0x82ef1c41, 0x7884005d), TOBN(0xa2d4ec17, 0xffffcbae),
+ TOBN(0x9161c53f, 0x8aa95e66), TOBN(0x5ee104e1, 0xc5fee0d0)}},
+ {{TOBN(0x562e4cec, 0xc135b208), TOBN(0x74e1b265, 0x4783f47d),
+ TOBN(0x6d2a506c, 0x5a3f3b30), TOBN(0xecead9f4, 0xc16762fc)},
+ {TOBN(0xf29dd4b2, 0xe286e5b9), TOBN(0x1b0fadc0, 0x83bb3c61),
+ TOBN(0x7a75023e, 0x7fac29a4), TOBN(0xc086d5f1, 0xc9477fa3)}},
+ {{TOBN(0x0fc61135, 0x2f6f3076), TOBN(0xc99ffa23, 0xe3912a9a),
+ TOBN(0x6a0b0685, 0xd2f8ba3d), TOBN(0xfdc777e8, 0xe93358a4)},
+ {TOBN(0x94a787bb, 0x35415f04), TOBN(0x640c2d6a, 0x4d23fea4),
+ TOBN(0x9de917da, 0x153a35b5), TOBN(0x793e8d07, 0x5d5cd074)}},
+ {{TOBN(0xf4f87653, 0x2de45068), TOBN(0x37c7a7e8, 0x9e2e1f6e),
+ TOBN(0xd0825fa2, 0xa3584069), TOBN(0xaf2cea7c, 0x1727bf42)},
+ {TOBN(0x0360a4fb, 0x9e4785a9), TOBN(0xe5fda49c, 0x27299f4a),
+ TOBN(0x48068e13, 0x71ac2f71), TOBN(0x83d0687b, 0x9077666f)}},
+ {{TOBN(0x6d3883b2, 0x15d02819), TOBN(0x6d0d7550, 0x40dd9a35),
+ TOBN(0x61d7cbf9, 0x1d2b469f), TOBN(0xf97b232f, 0x2efc3115)},
+ {TOBN(0xa551d750, 0xb24bcbc7), TOBN(0x11ea4949, 0x88a1e356),
+ TOBN(0x7669f031, 0x93cb7501), TOBN(0x595dc55e, 0xca737b8a)}},
+ {{TOBN(0xa4a319ac, 0xd837879f), TOBN(0x6fc1b49e, 0xed6b67b0),
+ TOBN(0xe3959933, 0x32f1f3af), TOBN(0x966742eb, 0x65432a2e)},
+ {TOBN(0x4b8dc9fe, 0xb4966228), TOBN(0x96cc6312, 0x43f43950),
+ TOBN(0x12068859, 0xc9b731ee), TOBN(0x7b948dc3, 0x56f79968)}},
+ {{TOBN(0x61e4ad32, 0xed1f8008), TOBN(0xe6c9267a, 0xd8b17538),
+ TOBN(0x1ac7c5eb, 0x857ff6fb), TOBN(0x994baaa8, 0x55f2fb10)},
+ {TOBN(0x84cf14e1, 0x1d248018), TOBN(0x5a39898b, 0x628ac508),
+ TOBN(0x14fde97b, 0x5fa944f5), TOBN(0xed178030, 0xd12e5ac7)}},
+ {{TOBN(0x042c2af4, 0x97e2feb4), TOBN(0xd36a42d7, 0xaebf7313),
+ TOBN(0x49d2c9eb, 0x084ffdd7), TOBN(0x9f8aa54b, 0x2ef7c76a)},
+ {TOBN(0x9200b7ba, 0x09895e70), TOBN(0x3bd0c66f, 0xddb7fb58),
+ TOBN(0x2d97d108, 0x78eb4cbb), TOBN(0x2d431068, 0xd84bde31)}},
+ {{TOBN(0x4b523eb7, 0x172ccd1f), TOBN(0x7323cb28, 0x30a6a892),
+ TOBN(0x97082ec0, 0xcfe153eb), TOBN(0xe97f6b6a, 0xf2aadb97)},
+ {TOBN(0x1d3d393e, 0xd1a83da1), TOBN(0xa6a7f9c7, 0x804b2a68),
+ TOBN(0x4a688b48, 0x2d0cb71e), TOBN(0xa9b4cc5f, 0x40585278)}},
+ {{TOBN(0x5e5db46a, 0xcb66e132), TOBN(0xf1be963a, 0x0d925880),
+ TOBN(0x944a7027, 0x0317b9e2), TOBN(0xe266f959, 0x48603d48)},
+ {TOBN(0x98db6673, 0x5c208899), TOBN(0x90472447, 0xa2fb18a3),
+ TOBN(0x8a966939, 0x777c619f), TOBN(0x3798142a, 0x2a3be21b)}},
+ {{TOBN(0xb4241cb1, 0x3298b343), TOBN(0xa3a14e49, 0xb44f65a1),
+ TOBN(0xc5f4d6cd, 0x3ac77acd), TOBN(0xd0288cb5, 0x52b6fc3c)},
+ {TOBN(0xd5cc8c2f, 0x1c040abc), TOBN(0xb675511e, 0x06bf9b4a),
+ TOBN(0xd667da37, 0x9b3aa441), TOBN(0x460d45ce, 0x51601f72)}},
+ {{TOBN(0xe2f73c69, 0x6755ff89), TOBN(0xdd3cf7e7, 0x473017e6),
+ TOBN(0x8ef5689d, 0x3cf7600d), TOBN(0x948dc4f8, 0xb1fc87b4)},
+ {TOBN(0xd9e9fe81, 0x4ea53299), TOBN(0x2d921ca2, 0x98eb6028),
+ TOBN(0xfaecedfd, 0x0c9803fc), TOBN(0xf38ae891, 0x4d7b4745)}},
+ {{TOBN(0xd8c5fccf, 0xc5e3a3d8), TOBN(0xbefd904c, 0x4079dfbf),
+ TOBN(0xbc6d6a58, 0xfead0197), TOBN(0x39227077, 0x695532a4)},
+ {TOBN(0x09e23e6d, 0xdbef42f5), TOBN(0x7e449b64, 0x480a9908),
+ TOBN(0x7b969c1a, 0xad9a2e40), TOBN(0x6231d792, 0x9591c2a4)}},
+ {{TOBN(0x87151456, 0x0f664534), TOBN(0x85ceae7c, 0x4b68f103),
+ TOBN(0xac09c4ae, 0x65578ab9), TOBN(0x33ec6868, 0xf044b10c)},
+ {TOBN(0x6ac4832b, 0x3a8ec1f1), TOBN(0x5509d128, 0x5847d5ef),
+ TOBN(0xf909604f, 0x763f1574), TOBN(0xb16c4303, 0xc32f63c4)}},
+ {{TOBN(0xb6ab2014, 0x7ca23cd3), TOBN(0xcaa7a5c6, 0xa391849d),
+ TOBN(0x5b0673a3, 0x75678d94), TOBN(0xc982ddd4, 0xdd303e64)},
+ {TOBN(0xfd7b000b, 0x5db6f971), TOBN(0xbba2cb1f, 0x6f876f92),
+ TOBN(0xc77332a3, 0x3c569426), TOBN(0xa159100c, 0x570d74f8)}},
+ {{TOBN(0xfd16847f, 0xdec67ef5), TOBN(0x742ee464, 0x233e76b7),
+ TOBN(0x0b8e4134, 0xefc2b4c8), TOBN(0xca640b86, 0x42a3e521)},
+ {TOBN(0x653a0190, 0x8ceb6aa9), TOBN(0x313c300c, 0x547852d5),
+ TOBN(0x24e4ab12, 0x6b237af7), TOBN(0x2ba90162, 0x8bb47af8)}},
+ {{TOBN(0x3d5e58d6, 0xa8219bb7), TOBN(0xc691d0bd, 0x1b06c57f),
+ TOBN(0x0ae4cb10, 0xd257576e), TOBN(0x3569656c, 0xd54a3dc3)},
+ {TOBN(0xe5ebaebd, 0x94cda03a), TOBN(0x934e82d3, 0x162bfe13),
+ TOBN(0x450ac0ba, 0xe251a0c6), TOBN(0x480b9e11, 0xdd6da526)}},
+ {{TOBN(0x00467bc5, 0x8cce08b5), TOBN(0xb636458c, 0x7f178d55),
+ TOBN(0xc5748bae, 0xa677d806), TOBN(0x2763a387, 0xdfa394eb)},
+ {TOBN(0xa12b448a, 0x7d3cebb6), TOBN(0xe7adda3e, 0x6f20d850),
+ TOBN(0xf63ebce5, 0x1558462c), TOBN(0x58b36143, 0x620088a8)}},
+ {{TOBN(0x8a2cc3ca, 0x4d63c0ee), TOBN(0x51233117, 0x0fe948ce),
+ TOBN(0x7463fd85, 0x222ef33b), TOBN(0xadf0c7dc, 0x7c603d6c)},
+ {TOBN(0x0ec32d3b, 0xfe7765e5), TOBN(0xccaab359, 0xbf380409),
+ TOBN(0xbdaa84d6, 0x8e59319c), TOBN(0xd9a4c280, 0x9c80c34d)}},
+ {{TOBN(0xa9d89488, 0xa059c142), TOBN(0x6f5ae714, 0xff0b9346),
+ TOBN(0x068f237d, 0x16fb3664), TOBN(0x5853e4c4, 0x363186ac)},
+ {TOBN(0xe2d87d23, 0x63c52f98), TOBN(0x2ec4a766, 0x81828876),
+ TOBN(0x47b864fa, 0xe14e7b1c), TOBN(0x0c0bc0e5, 0x69192408)}},
+ {{TOBN(0xe4d7681d, 0xb82e9f3e), TOBN(0x83200f0b, 0xdf25e13c),
+ TOBN(0x8909984c, 0x66f27280), TOBN(0x462d7b00, 0x75f73227)},
+ {TOBN(0xd90ba188, 0xf2651798), TOBN(0x74c6e18c, 0x36ab1c34),
+ TOBN(0xab256ea3, 0x5ef54359), TOBN(0x03466612, 0xd1aa702f)}},
+ {{TOBN(0x624d6049, 0x2ed22e91), TOBN(0x6fdfe0b5, 0x6f072822),
+ TOBN(0xeeca1115, 0x39ce2271), TOBN(0x98100a4f, 0xdb01614f)},
+ {TOBN(0xb6b0daa2, 0xa35c628f), TOBN(0xb6f94d2e, 0xc87e9a47),
+ TOBN(0xc6773259, 0x1d57d9ce), TOBN(0xf70bfeec, 0x03884a7b)}},
+ {{TOBN(0x5fb35ccf, 0xed2bad01), TOBN(0xa155cbe3, 0x1da6a5c7),
+ TOBN(0xc2e2594c, 0x30a92f8f), TOBN(0x649c89ce, 0x5bfafe43)},
+ {TOBN(0xd158667d, 0xe9ff257a), TOBN(0x9b359611, 0xf32c50ae),
+ TOBN(0x4b00b20b, 0x906014cf), TOBN(0xf3a8cfe3, 0x89bc7d3d)}},
+ {{TOBN(0x4ff23ffd, 0x248a7d06), TOBN(0x80c5bfb4, 0x878873fa),
+ TOBN(0xb7d9ad90, 0x05745981), TOBN(0x179c85db, 0x3db01994)},
+ {TOBN(0xba41b062, 0x61a6966c), TOBN(0x4d82d052, 0xeadce5a8),
+ TOBN(0x9e91cd3b, 0xa5e6a318), TOBN(0x47795f4f, 0x95b2dda0)}},
+ {{TOBN(0xecfd7c1f, 0xd55a897c), TOBN(0x009194ab, 0xb29110fb),
+ TOBN(0x5f0e2046, 0xe381d3b0), TOBN(0x5f3425f6, 0xa98dd291)},
+ {TOBN(0xbfa06687, 0x730d50da), TOBN(0x0423446c, 0x4b083b7f),
+ TOBN(0x397a247d, 0xd69d3417), TOBN(0xeb629f90, 0x387ba42a)}},
+ {{TOBN(0x1ee426cc, 0xd5cd79bf), TOBN(0x0032940b, 0x946c6e18),
+ TOBN(0x1b1e8ae0, 0x57477f58), TOBN(0xe94f7d34, 0x6d823278)},
+ {TOBN(0xc747cb96, 0x782ba21a), TOBN(0xc5254469, 0xf72b33a5),
+ TOBN(0x772ef6de, 0xc7f80c81), TOBN(0xd73acbfe, 0x2cd9e6b5)}},
+ {{TOBN(0x4075b5b1, 0x49ee90d9), TOBN(0x785c339a, 0xa06e9eba),
+ TOBN(0xa1030d5b, 0xabf825e0), TOBN(0xcec684c3, 0xa42931dc)},
+ {TOBN(0x42ab62c9, 0xc1586e63), TOBN(0x45431d66, 0x5ab43f2b),
+ TOBN(0x57c8b2c0, 0x55f7835d), TOBN(0x033da338, 0xc1b7f865)}},
+ {{TOBN(0x283c7513, 0xcaa76097), TOBN(0x0a624fa9, 0x36c83906),
+ TOBN(0x6b20afec, 0x715af2c7), TOBN(0x4b969974, 0xeba78bfd)},
+ {TOBN(0x220755cc, 0xd921d60e), TOBN(0x9b944e10, 0x7baeca13),
+ TOBN(0x04819d51, 0x5ded93d4), TOBN(0x9bbff86e, 0x6dddfd27)}},
+ {{TOBN(0x6b344130, 0x77adc612), TOBN(0xa7496529, 0xbbd803a0),
+ TOBN(0x1a1baaa7, 0x6d8805bd), TOBN(0xc8403902, 0x470343ad)},
+ {TOBN(0x39f59f66, 0x175adff1), TOBN(0x0b26d7fb, 0xb7d8c5b7),
+ TOBN(0xa875f5ce, 0x529d75e3), TOBN(0x85efc7e9, 0x41325cc2)}},
+ {{TOBN(0x21950b42, 0x1ff6acd3), TOBN(0xffe70484, 0x53dc6909),
+ TOBN(0xff4cd0b2, 0x28766127), TOBN(0xabdbe608, 0x4fb7db2b)},
+ {TOBN(0x837c9228, 0x5e1109e8), TOBN(0x26147d27, 0xf4645b5a),
+ TOBN(0x4d78f592, 0xf7818ed8), TOBN(0xd394077e, 0xf247fa36)}},
+ {{TOBN(0x0fb9c2d0, 0x488c171a), TOBN(0xa78bfbaa, 0x13685278),
+ TOBN(0xedfbe268, 0xd5b1fa6a), TOBN(0x0dceb8db, 0x2b7eaba7)},
+ {TOBN(0xbf9e8089, 0x9ae2b710), TOBN(0xefde7ae6, 0xa4449c96),
+ TOBN(0x43b7716b, 0xcc143a46), TOBN(0xd7d34194, 0xc3628c13)}},
+ {{TOBN(0x508cec1c, 0x3b3f64c9), TOBN(0xe20bc0ba, 0x1e5edf3f),
+ TOBN(0xda1deb85, 0x2f4318d4), TOBN(0xd20ebe0d, 0x5c3fa443)},
+ {TOBN(0x370b4ea7, 0x73241ea3), TOBN(0x61f1511c, 0x5e1a5f65),
+ TOBN(0x99a5e23d, 0x82681c62), TOBN(0xd731e383, 0xa2f54c2d)}},
+ {{TOBN(0x2692f36e, 0x83445904), TOBN(0x2e0ec469, 0xaf45f9c0),
+ TOBN(0x905a3201, 0xc67528b7), TOBN(0x88f77f34, 0xd0e5e542)},
+ {TOBN(0xf67a8d29, 0x5864687c), TOBN(0x23b92eae, 0x22df3562),
+ TOBN(0x5c27014b, 0x9bbec39e), TOBN(0x7ef2f226, 0x9c0f0f8d)}},
+ {{TOBN(0x97359638, 0x546c4d8d), TOBN(0x5f9c3fc4, 0x92f24679),
+ TOBN(0x912e8bed, 0xa8c8acd9), TOBN(0xec3a318d, 0x306634b0)},
+ {TOBN(0x80167f41, 0xc31cb264), TOBN(0x3db82f6f, 0x522113f2),
+ TOBN(0xb155bcd2, 0xdcafe197), TOBN(0xfba1da59, 0x43465283)}},
+ {{TOBN(0xa0425b8e, 0xb212cf53), TOBN(0x4f2e512e, 0xf8557c5f),
+ TOBN(0xc1286ff9, 0x25c4d56c), TOBN(0xbb8a0fea, 0xee26c851)},
+ {TOBN(0xc28f70d2, 0xe7d6107e), TOBN(0x7ee0c444, 0xe76265aa),
+ TOBN(0x3df277a4, 0x1d1936b1), TOBN(0x1a556e3f, 0xea9595eb)}},
+ {{TOBN(0x258bbbf9, 0xe7305683), TOBN(0x31eea5bf, 0x07ef5be6),
+ TOBN(0x0deb0e4a, 0x46c814c1), TOBN(0x5cee8449, 0xa7b730dd)},
+ {TOBN(0xeab495c5, 0xa0182bde), TOBN(0xee759f87, 0x9e27a6b4),
+ TOBN(0xc2cf6a68, 0x80e518ca), TOBN(0x25e8013f, 0xf14cf3f4)}},
+ {{TOBN(0x8fc44140, 0x7e8d7a14), TOBN(0xbb1ff3ca, 0x9556f36a),
+ TOBN(0x6a844385, 0x14600044), TOBN(0xba3f0c4a, 0x7451ae63)},
+ {TOBN(0xdfcac25b, 0x1f9af32a), TOBN(0x01e0db86, 0xb1f2214b),
+ TOBN(0x4e9a5bc2, 0xa4b596ac), TOBN(0x83927681, 0x026c2c08)}},
+ {{TOBN(0x3ec832e7, 0x7acaca28), TOBN(0x1bfeea57, 0xc7385b29),
+ TOBN(0x068212e3, 0xfd1eaf38), TOBN(0xc1329830, 0x6acf8ccc)},
+ {TOBN(0xb909f2db, 0x2aac9e59), TOBN(0x5748060d, 0xb661782a),
+ TOBN(0xc5ab2632, 0xc79b7a01), TOBN(0xda44c6c6, 0x00017626)}},
+ {{TOBN(0xf26c00e8, 0xa7ea82f0), TOBN(0x99cac80d, 0xe4299aaf),
+ TOBN(0xd66fe3b6, 0x7ed78be1), TOBN(0x305f725f, 0x648d02cd)},
+ {TOBN(0x33ed1bc4, 0x623fb21b), TOBN(0xfa70533e, 0x7a6319ad),
+ TOBN(0x17ab562d, 0xbe5ffb3e), TOBN(0x06374994, 0x56674741)}},
+ {{TOBN(0x69d44ed6, 0x5c46aa8e), TOBN(0x2100d5d3, 0xa8d063d1),
+ TOBN(0xcb9727ea, 0xa2d17c36), TOBN(0x4c2bab1b, 0x8add53b7)},
+ {TOBN(0xa084e90c, 0x15426704), TOBN(0x778afcd3, 0xa837ebea),
+ TOBN(0x6651f701, 0x7ce477f8), TOBN(0xa0624998, 0x46fb7a8b)}},
+ {{TOBN(0xdc1e6828, 0xed8a6e19), TOBN(0x33fc2336, 0x4189d9c7),
+ TOBN(0x026f8fe2, 0x671c39bc), TOBN(0xd40c4ccd, 0xbc6f9915)},
+ {TOBN(0xafa135bb, 0xf80e75ca), TOBN(0x12c651a0, 0x22adff2c),
+ TOBN(0xc40a04bd, 0x4f51ad96), TOBN(0x04820109, 0xbbe4e832)}},
+ {{TOBN(0x3667eb1a, 0x7f4c04cc), TOBN(0x59556621, 0xa9404f84),
+ TOBN(0x71cdf653, 0x7eceb50a), TOBN(0x994a44a6, 0x9b8335fa)},
+ {TOBN(0xd7faf819, 0xdbeb9b69), TOBN(0x473c5680, 0xeed4350d),
+ TOBN(0xb6658466, 0xda44bba2), TOBN(0x0d1bc780, 0x872bdbf3)}},
+ {{TOBN(0xe535f175, 0xa1962f91), TOBN(0x6ed7e061, 0xed58f5a7),
+ TOBN(0x177aa4c0, 0x2089a233), TOBN(0x0dbcb03a, 0xe539b413)},
+ {TOBN(0xe3dc424e, 0xbb32e38e), TOBN(0x6472e5ef, 0x6806701e),
+ TOBN(0xdd47ff98, 0x814be9ee), TOBN(0x6b60cfff, 0x35ace009)}},
+ {{TOBN(0xb8d3d931, 0x9ff91fe5), TOBN(0x039c4800, 0xf0518eed),
+ TOBN(0x95c37632, 0x9182cb26), TOBN(0x0763a434, 0x82fc568d)},
+ {TOBN(0x707c04d5, 0x383e76ba), TOBN(0xac98b930, 0x824e8197),
+ TOBN(0x92bf7c8f, 0x91230de0), TOBN(0x90876a01, 0x40959b70)}},
+ {{TOBN(0xdb6d96f3, 0x05968b80), TOBN(0x380a0913, 0x089f73b9),
+ TOBN(0x7da70b83, 0xc2c61e01), TOBN(0x95fb8394, 0x569b38c7)},
+ {TOBN(0x9a3c6512, 0x80edfe2f), TOBN(0x8f726bb9, 0x8faeaf82),
+ TOBN(0x8010a4a0, 0x78424bf8), TOBN(0x29672044, 0x0e844970)}}},
+ {{{TOBN(0x63c5cb81, 0x7a2ad62a), TOBN(0x7ef2b6b9, 0xac62ff54),
+ TOBN(0x3749bba4, 0xb3ad9db5), TOBN(0xad311f2c, 0x46d5a617)},
+ {TOBN(0xb77a8087, 0xc2ff3b6d), TOBN(0xb46feaf3, 0x367834ff),
+ TOBN(0xf8aa266d, 0x75d6b138), TOBN(0xfa38d320, 0xec008188)}},
+ {{TOBN(0x486d8ffa, 0x696946fc), TOBN(0x50fbc6d8, 0xb9cba56d),
+ TOBN(0x7e3d423e, 0x90f35a15), TOBN(0x7c3da195, 0xc0dd962c)},
+ {TOBN(0xe673fdb0, 0x3cfd5d8b), TOBN(0x0704b7c2, 0x889dfca5),
+ TOBN(0xf6ce581f, 0xf52305aa), TOBN(0x399d49eb, 0x914d5e53)}},
+ {{TOBN(0x380a496d, 0x6ec293cd), TOBN(0x733dbda7, 0x8e7051f5),
+ TOBN(0x037e388d, 0xb849140a), TOBN(0xee4b32b0, 0x5946dbf6)},
+ {TOBN(0xb1c4fda9, 0xcae368d1), TOBN(0x5001a7b0, 0xfdb0b2f3),
+ TOBN(0x6df59374, 0x2e3ac46e), TOBN(0x4af675f2, 0x39b3e656)}},
+ {{TOBN(0x44e38110, 0x39949296), TOBN(0x5b63827b, 0x361db1b5),
+ TOBN(0x3e5323ed, 0x206eaff5), TOBN(0x942370d2, 0xc21f4290)},
+ {TOBN(0xf2caaf2e, 0xe0d985a1), TOBN(0x192cc64b, 0x7239846d),
+ TOBN(0x7c0b8f47, 0xae6312f8), TOBN(0x7dc61f91, 0x96620108)}},
+ {{TOBN(0xb830fb5b, 0xc2da7de9), TOBN(0xd0e643df, 0x0ff8d3be),
+ TOBN(0x31ee77ba, 0x188a9641), TOBN(0x4e8aa3aa, 0xbcf6d502)},
+ {TOBN(0xf9fb6532, 0x9a49110f), TOBN(0xd18317f6, 0x2dd6b220),
+ TOBN(0x7e3ced41, 0x52c3ea5a), TOBN(0x0d296a14, 0x7d579c4a)}},
+ {{TOBN(0x35d6a53e, 0xed4c3717), TOBN(0x9f8240cf, 0x3d0ed2a3),
+ TOBN(0x8c0d4d05, 0xe5543aa5), TOBN(0x45d5bbfb, 0xdd33b4b4)},
+ {TOBN(0xfa04cc73, 0x137fd28e), TOBN(0x862ac6ef, 0xc73b3ffd),
+ TOBN(0x403ff9f5, 0x31f51ef2), TOBN(0x34d5e0fc, 0xbc73f5a2)}},
+ {{TOBN(0xf2526820, 0x08913f4f), TOBN(0xea20ed61, 0xeac93d95),
+ TOBN(0x51ed38b4, 0x6ca6b26c), TOBN(0x8662dcbc, 0xea4327b0)},
+ {TOBN(0x6daf295c, 0x725d2aaa), TOBN(0xbad2752f, 0x8e52dcda),
+ TOBN(0x2210e721, 0x0b17dacc), TOBN(0xa37f7912, 0xd51e8232)}},
+ {{TOBN(0x4f7081e1, 0x44cc3add), TOBN(0xd5ffa1d6, 0x87be82cf),
+ TOBN(0x89890b6c, 0x0edd6472), TOBN(0xada26e1a, 0x3ed17863)},
+ {TOBN(0x276f2715, 0x63483caa), TOBN(0xe6924cd9, 0x2f6077fd),
+ TOBN(0x05a7fe98, 0x0a466e3c), TOBN(0xf1c794b0, 0xb1902d1f)}},
+ {{TOBN(0xe5213688, 0x82a8042c), TOBN(0xd931cfaf, 0xcd278298),
+ TOBN(0x069a0ae0, 0xf597a740), TOBN(0x0adbb3f3, 0xeb59107c)},
+ {TOBN(0x983e951e, 0x5eaa8eb8), TOBN(0xe663a8b5, 0x11b48e78),
+ TOBN(0x1631cc0d, 0x8a03f2c5), TOBN(0x7577c11e, 0x11e271e2)}},
+ {{TOBN(0x33b2385c, 0x08369a90), TOBN(0x2990c59b, 0x190eb4f8),
+ TOBN(0x819a6145, 0xc68eac80), TOBN(0x7a786d62, 0x2ec4a014)},
+ {TOBN(0x33faadbe, 0x20ac3a8d), TOBN(0x31a21781, 0x5aba2d30),
+ TOBN(0x209d2742, 0xdba4f565), TOBN(0xdb2ce9e3, 0x55aa0fbb)}},
+ {{TOBN(0x8cef334b, 0x168984df), TOBN(0xe81dce17, 0x33879638),
+ TOBN(0xf6e6949c, 0x263720f0), TOBN(0x5c56feaf, 0xf593cbec)},
+ {TOBN(0x8bff5601, 0xfde58c84), TOBN(0x74e24117, 0x2eccb314),
+ TOBN(0xbcf01b61, 0x4c9a8a78), TOBN(0xa233e35e, 0x544c9868)}},
+ {{TOBN(0xb3156bf3, 0x8bd7aff1), TOBN(0x1b5ee4cb, 0x1d81b146),
+ TOBN(0x7ba1ac41, 0xd628a915), TOBN(0x8f3a8f9c, 0xfd89699e)},
+ {TOBN(0x7329b9c9, 0xa0748be7), TOBN(0x1d391c95, 0xa92e621f),
+ TOBN(0xe51e6b21, 0x4d10a837), TOBN(0xd255f53a, 0x4947b435)}},
+ {{TOBN(0x07669e04, 0xf1788ee3), TOBN(0xc14f27af, 0xa86938a2),
+ TOBN(0x8b47a334, 0xe93a01c0), TOBN(0xff627438, 0xd9366808)},
+ {TOBN(0x7a0985d8, 0xca2a5965), TOBN(0x3d9a5542, 0xd6e9b9b3),
+ TOBN(0xc23eb80b, 0x4cf972e8), TOBN(0x5c1c33bb, 0x4fdf72fd)}},
+ {{TOBN(0x0c4a58d4, 0x74a86108), TOBN(0xf8048a8f, 0xee4c5d90),
+ TOBN(0xe3c7c924, 0xe86d4c80), TOBN(0x28c889de, 0x056a1e60)},
+ {TOBN(0x57e2662e, 0xb214a040), TOBN(0xe8c48e98, 0x37e10347),
+ TOBN(0x87742862, 0x80ac748a), TOBN(0xf1c24022, 0x186b06f2)}},
+ {{TOBN(0xac2dd4c3, 0x5f74040a), TOBN(0x409aeb71, 0xfceac957),
+ TOBN(0x4fbad782, 0x55c4ec23), TOBN(0xb359ed61, 0x8a7b76ec)},
+ {TOBN(0x12744926, 0xed6f4a60), TOBN(0xe21e8d7f, 0x4b912de3),
+ TOBN(0xe2575a59, 0xfc705a59), TOBN(0x72f1d4de, 0xed2dbc0e)}},
+ {{TOBN(0x3d2b24b9, 0xeb7926b8), TOBN(0xbff88cb3, 0xcdbe5509),
+ TOBN(0xd0f399af, 0xe4dd640b), TOBN(0x3c5fe130, 0x2f76ed45)},
+ {TOBN(0x6f3562f4, 0x3764fb3d), TOBN(0x7b5af318, 0x3151b62d),
+ TOBN(0xd5bd0bc7, 0xd79ce5f3), TOBN(0xfdaf6b20, 0xec66890f)}},
+ {{TOBN(0x735c67ec, 0x6063540c), TOBN(0x50b259c2, 0xe5f9cb8f),
+ TOBN(0xb8734f9a, 0x3f99c6ab), TOBN(0xf8cc13d5, 0xa3a7bc85)},
+ {TOBN(0x80c1b305, 0xc5217659), TOBN(0xfe5364d4, 0x4ec12a54),
+ TOBN(0xbd87045e, 0x681345fe), TOBN(0x7f8efeb1, 0x582f897f)}},
+ {{TOBN(0xe8cbf1e5, 0xd5923359), TOBN(0xdb0cea9d, 0x539b9fb0),
+ TOBN(0x0c5b34cf, 0x49859b98), TOBN(0x5e583c56, 0xa4403cc6)},
+ {TOBN(0x11fc1a2d, 0xd48185b7), TOBN(0xc93fbc7e, 0x6e521787),
+ TOBN(0x47e7a058, 0x05105b8b), TOBN(0x7b4d4d58, 0xdb8260c8)}},
+ {{TOBN(0xe33930b0, 0x46eb842a), TOBN(0x8e844a9a, 0x7bdae56d),
+ TOBN(0x34ef3a9e, 0x13f7fdfc), TOBN(0xb3768f82, 0x636ca176)},
+ {TOBN(0x2821f4e0, 0x4e09e61c), TOBN(0x414dc3a1, 0xa0c7cddc),
+ TOBN(0xd5379437, 0x54945fcd), TOBN(0x151b6eef, 0xb3555ff1)}},
+ {{TOBN(0xb31bd613, 0x6339c083), TOBN(0x39ff8155, 0xdfb64701),
+ TOBN(0x7c3388d2, 0xe29604ab), TOBN(0x1e19084b, 0xa6b10442)},
+ {TOBN(0x17cf54c0, 0xeccd47ef), TOBN(0x89693385, 0x4a5dfb30),
+ TOBN(0x69d023fb, 0x47daf9f6), TOBN(0x9222840b, 0x7d91d959)}},
+ {{TOBN(0x439108f5, 0x803bac62), TOBN(0x0b7dd91d, 0x379bd45f),
+ TOBN(0xd651e827, 0xca63c581), TOBN(0x5c5d75f6, 0x509c104f)},
+ {TOBN(0x7d5fc738, 0x1f2dc308), TOBN(0x20faa7bf, 0xd98454be),
+ TOBN(0x95374bee, 0xa517b031), TOBN(0xf036b9b1, 0x642692ac)}},
+ {{TOBN(0xc5106109, 0x39842194), TOBN(0xb7e2353e, 0x49d05295),
+ TOBN(0xfc8c1d5c, 0xefb42ee0), TOBN(0xe04884eb, 0x08ce811c)},
+ {TOBN(0xf1f75d81, 0x7419f40e), TOBN(0x5b0ac162, 0xa995c241),
+ TOBN(0x120921bb, 0xc4c55646), TOBN(0x713520c2, 0x8d33cf97)}},
+ {{TOBN(0xb4a65a5c, 0xe98c5100), TOBN(0x6cec871d, 0x2ddd0f5a),
+ TOBN(0x251f0b7f, 0x9ba2e78b), TOBN(0x224a8434, 0xce3a2a5f)},
+ {TOBN(0x26827f61, 0x25f5c46f), TOBN(0x6a22bedc, 0x48545ec0),
+ TOBN(0x25ae5fa0, 0xb1bb5cdc), TOBN(0xd693682f, 0xfcb9b98f)}},
+ {{TOBN(0x32027fe8, 0x91e5d7d3), TOBN(0xf14b7d17, 0x73a07678),
+ TOBN(0xf88497b3, 0xc0dfdd61), TOBN(0xf7c2eec0, 0x2a8c4f48)},
+ {TOBN(0xaa5573f4, 0x3756e621), TOBN(0xc013a240, 0x1825b948),
+ TOBN(0x1c03b345, 0x63878572), TOBN(0xa0472bea, 0x653a4184)}},
+ {{TOBN(0xf4222e27, 0x0ac69a80), TOBN(0x34096d25, 0xf51e54f6),
+ TOBN(0x00a648cb, 0x8fffa591), TOBN(0x4e87acdc, 0x69b6527f)},
+ {TOBN(0x0575e037, 0xe285ccb4), TOBN(0x188089e4, 0x50ddcf52),
+ TOBN(0xaa96c9a8, 0x870ff719), TOBN(0x74a56cd8, 0x1fc7e369)}},
+ {{TOBN(0x41d04ee2, 0x1726931a), TOBN(0x0bbbb2c8, 0x3660ecfd),
+ TOBN(0xa6ef6de5, 0x24818e18), TOBN(0xe421cc51, 0xe7d57887)},
+ {TOBN(0xf127d208, 0xbea87be6), TOBN(0x16a475d3, 0xb1cdd682),
+ TOBN(0x9db1b684, 0x439b63f7), TOBN(0x5359b3db, 0xf0f113b6)}},
+ {{TOBN(0xdfccf1de, 0x8bf06e31), TOBN(0x1fdf8f44, 0xdd383901),
+ TOBN(0x10775cad, 0x5017e7d2), TOBN(0xdfc3a597, 0x58d11eef)},
+ {TOBN(0x6ec9c8a0, 0xb1ecff10), TOBN(0xee6ed6cc, 0x28400549),
+ TOBN(0xb5ad7bae, 0x1b4f8d73), TOBN(0x61b4f11d, 0xe00aaab9)}},
+ {{TOBN(0x7b32d69b, 0xd4eff2d7), TOBN(0x88ae6771, 0x4288b60f),
+ TOBN(0x159461b4, 0x37a1e723), TOBN(0x1f3d4789, 0x570aae8c)},
+ {TOBN(0x869118c0, 0x7f9871da), TOBN(0x35fbda78, 0xf635e278),
+ TOBN(0x738f3641, 0xe1541dac), TOBN(0x6794b13a, 0xc0dae45f)}},
+ {{TOBN(0x065064ac, 0x09cc0917), TOBN(0x27c53729, 0xc68540fd),
+ TOBN(0x0d2d4c8e, 0xef227671), TOBN(0xd23a9f80, 0xa1785a04)},
+ {TOBN(0x98c59528, 0x52650359), TOBN(0xfa09ad01, 0x74a1acad),
+ TOBN(0x082d5a29, 0x0b55bf5c), TOBN(0xa40f1c67, 0x419b8084)}},
+ {{TOBN(0x3a5c752e, 0xdcc18770), TOBN(0x4baf1f2f, 0x8825c3a5),
+ TOBN(0xebd63f74, 0x21b153ed), TOBN(0xa2383e47, 0xb2f64723)},
+ {TOBN(0xe7bf620a, 0x2646d19a), TOBN(0x56cb44ec, 0x03c83ffd),
+ TOBN(0xaf7267c9, 0x4f6be9f1), TOBN(0x8b2dfd7b, 0xc06bb5e9)}},
+ {{TOBN(0xb87072f2, 0xa672c5c7), TOBN(0xeacb11c8, 0x0d53c5e2),
+ TOBN(0x22dac29d, 0xff435932), TOBN(0x37bdb99d, 0x4408693c)},
+ {TOBN(0xf6e62fb6, 0x2899c20f), TOBN(0x3535d512, 0x447ece24),
+ TOBN(0xfbdc6b88, 0xff577ce3), TOBN(0x726693bd, 0x190575f2)}},
+ {{TOBN(0x6772b0e5, 0xab4b35a2), TOBN(0x1d8b6001, 0xf5eeaacf),
+ TOBN(0x728f7ce4, 0x795b9580), TOBN(0x4a20ed2a, 0x41fb81da)},
+ {TOBN(0x9f685cd4, 0x4fec01e6), TOBN(0x3ed7ddcc, 0xa7ff50ad),
+ TOBN(0x460fd264, 0x0c2d97fd), TOBN(0x3a241426, 0xeb82f4f9)}},
+ {{TOBN(0x17d1df2c, 0x6a8ea820), TOBN(0xb2b50d3b, 0xf22cc254),
+ TOBN(0x03856cba, 0xb7291426), TOBN(0x87fd26ae, 0x04f5ee39)},
+ {TOBN(0x9cb696cc, 0x02bee4ba), TOBN(0x53121804, 0x06820fd6),
+ TOBN(0xa5dfc269, 0x0212e985), TOBN(0x666f7ffa, 0x160f9a09)}},
+ {{TOBN(0xc503cd33, 0xbccd9617), TOBN(0x365dede4, 0xba7730a3),
+ TOBN(0x798c6355, 0x5ddb0786), TOBN(0xa6c3200e, 0xfc9cd3bc)},
+ {TOBN(0x060ffb2c, 0xe5e35efd), TOBN(0x99a4e25b, 0x5555a1c1),
+ TOBN(0x11d95375, 0xf70b3751), TOBN(0x0a57354a, 0x160e1bf6)}},
+ {{TOBN(0xecb3ae4b, 0xf8e4b065), TOBN(0x07a834c4, 0x2e53022b),
+ TOBN(0x1cd300b3, 0x8692ed96), TOBN(0x16a6f792, 0x61ee14ec)},
+ {TOBN(0x8f1063c6, 0x6a8649ed), TOBN(0xfbcdfcfe, 0x869f3e14),
+ TOBN(0x2cfb97c1, 0x00a7b3ec), TOBN(0xcea49b3c, 0x7130c2f1)}},
+ {{TOBN(0x462d044f, 0xe9d96488), TOBN(0x4b53d52e, 0x8182a0c1),
+ TOBN(0x84b6ddd3, 0x0391e9e9), TOBN(0x80ab7b48, 0xb1741a09)},
+ {TOBN(0xec0e15d4, 0x27d3317f), TOBN(0x8dfc1ddb, 0x1a64671e),
+ TOBN(0x93cc5d5f, 0xd49c5b92), TOBN(0xc995d53d, 0x3674a331)}},
+ {{TOBN(0x302e41ec, 0x090090ae), TOBN(0x2278a0cc, 0xedb06830),
+ TOBN(0x1d025932, 0xfbc99690), TOBN(0x0c32fbd2, 0xb80d68da)},
+ {TOBN(0xd79146da, 0xf341a6c1), TOBN(0xae0ba139, 0x1bef68a0),
+ TOBN(0xc6b8a563, 0x8d774b3a), TOBN(0x1cf307bd, 0x880ba4d7)}},
+ {{TOBN(0xc033bdc7, 0x19803511), TOBN(0xa9f97b3b, 0x8888c3be),
+ TOBN(0x3d68aebc, 0x85c6d05e), TOBN(0xc3b88a9d, 0x193919eb)},
+ {TOBN(0x2d300748, 0xc48b0ee3), TOBN(0x7506bc7c, 0x07a746c1),
+ TOBN(0xfc48437c, 0x6e6d57f3), TOBN(0x5bd71587, 0xcfeaa91a)}},
+ {{TOBN(0xa4ed0408, 0xc1bc5225), TOBN(0xd0b946db, 0x2719226d),
+ TOBN(0x109ecd62, 0x758d2d43), TOBN(0x75c8485a, 0x2751759b)},
+ {TOBN(0xb0b75f49, 0x9ce4177a), TOBN(0x4fa61a1e, 0x79c10c3d),
+ TOBN(0xc062d300, 0xa167fcd7), TOBN(0x4df3874c, 0x750f0fa8)}},
+ {{TOBN(0x29ae2cf9, 0x83dfedc9), TOBN(0xf8437134, 0x8d87631a),
+ TOBN(0xaf571711, 0x7429c8d2), TOBN(0x18d15867, 0x146d9272)},
+ {TOBN(0x83053ecf, 0x69769bb7), TOBN(0xc55eb856, 0xc479ab82),
+ TOBN(0x5ef7791c, 0x21b0f4b2), TOBN(0xaa5956ba, 0x3d491525)}},
+ {{TOBN(0x407a96c2, 0x9fe20eba), TOBN(0xf27168bb, 0xe52a5ad3),
+ TOBN(0x43b60ab3, 0xbf1d9d89), TOBN(0xe45c51ef, 0x710e727a)},
+ {TOBN(0xdfca5276, 0x099b4221), TOBN(0x8dc6407c, 0x2557a159),
+ TOBN(0x0ead8335, 0x91035895), TOBN(0x0a9db957, 0x9c55dc32)}},
+ {{TOBN(0xe40736d3, 0xdf61bc76), TOBN(0x13a619c0, 0x3f778cdb),
+ TOBN(0x6dd921a4, 0xc56ea28f), TOBN(0x76a52433, 0x2fa647b4)},
+ {TOBN(0x23591891, 0xac5bdc5d), TOBN(0xff4a1a72, 0xbac7dc01),
+ TOBN(0x9905e261, 0x62df8453), TOBN(0x3ac045df, 0xe63b265f)}},
+ {{TOBN(0x8a3f341b, 0xad53dba7), TOBN(0x8ec269cc, 0x837b625a),
+ TOBN(0xd71a2782, 0x3ae31189), TOBN(0x8fb4f9a3, 0x55e96120)},
+ {TOBN(0x804af823, 0xff9875cf), TOBN(0x23224f57, 0x5d442a9b),
+ TOBN(0x1c4d3b9e, 0xecc62679), TOBN(0x91da22fb, 0xa0e7ddb1)}},
+ {{TOBN(0xa370324d, 0x6c04a661), TOBN(0x9710d3b6, 0x5e376d17),
+ TOBN(0xed8c98f0, 0x3044e357), TOBN(0xc364ebbe, 0x6422701c)},
+ {TOBN(0x347f5d51, 0x7733d61c), TOBN(0xd55644b9, 0xcea826c3),
+ TOBN(0x80c6e0ad, 0x55a25548), TOBN(0x0aa7641d, 0x844220a7)}},
+ {{TOBN(0x1438ec81, 0x31810660), TOBN(0x9dfa6507, 0xde4b4043),
+ TOBN(0x10b515d8, 0xcc3e0273), TOBN(0x1b6066dd, 0x28d8cfb2)},
+ {TOBN(0xd3b04591, 0x9c9efebd), TOBN(0x425d4bdf, 0xa21c1ff4),
+ TOBN(0x5fe5af19, 0xd57607d3), TOBN(0xbbf773f7, 0x54481084)}},
+ {{TOBN(0x8435bd69, 0x94b03ed1), TOBN(0xd9ad1de3, 0x634cc546),
+ TOBN(0x2cf423fc, 0x00e420ca), TOBN(0xeed26d80, 0xa03096dd)},
+ {TOBN(0xd7f60be7, 0xa4db09d2), TOBN(0xf47f569d, 0x960622f7),
+ TOBN(0xe5925fd7, 0x7296c729), TOBN(0xeff2db26, 0x26ca2715)}},
+ {{TOBN(0xa6fcd014, 0xb913e759), TOBN(0x53da4786, 0x8ff4de93),
+ TOBN(0x14616d79, 0xc32068e1), TOBN(0xb187d664, 0xccdf352e)},
+ {TOBN(0xf7afb650, 0x1dc90b59), TOBN(0x8170e943, 0x7daa1b26),
+ TOBN(0xc8e3bdd8, 0x700c0a84), TOBN(0x6e8d345f, 0x6482bdfa)}},
+ {{TOBN(0x84cfbfa1, 0xc5c5ea50), TOBN(0xd3baf14c, 0x67960681),
+ TOBN(0x26398403, 0x0dd50942), TOBN(0xe4b7839c, 0x4716a663)},
+ {TOBN(0xd5f1f794, 0xe7de6dc0), TOBN(0x5cd0f4d4, 0x622aa7ce),
+ TOBN(0x5295f3f1, 0x59acfeec), TOBN(0x8d933552, 0x953e0607)}},
+ {{TOBN(0xc7db8ec5, 0x776c5722), TOBN(0xdc467e62, 0x2b5f290c),
+ TOBN(0xd4297e70, 0x4ff425a9), TOBN(0x4be924c1, 0x0cf7bb72)},
+ {TOBN(0x0d5dc5ae, 0xa1892131), TOBN(0x8bf8a8e3, 0xa705c992),
+ TOBN(0x73a0b064, 0x7a305ac5), TOBN(0x00c9ca4e, 0x9a8c77a8)}},
+ {{TOBN(0x5dfee80f, 0x83774bdd), TOBN(0x63131602, 0x85734485),
+ TOBN(0xa1b524ae, 0x914a69a9), TOBN(0xebc2ffaf, 0xd4e300d7)},
+ {TOBN(0x52c93db7, 0x7cfa46a5), TOBN(0x71e6161f, 0x21653b50),
+ TOBN(0x3574fc57, 0xa4bc580a), TOBN(0xc09015dd, 0xe1bc1253)}},
+ {{TOBN(0x4b7b47b2, 0xd174d7aa), TOBN(0x4072d8e8, 0xf3a15d04),
+ TOBN(0xeeb7d47f, 0xd6fa07ed), TOBN(0x6f2b9ff9, 0xedbdafb1)},
+ {TOBN(0x18c51615, 0x3760fe8a), TOBN(0x7a96e6bf, 0xf06c6c13),
+ TOBN(0x4d7a0410, 0x0ea2d071), TOBN(0xa1914e9b, 0x0be2a5ce)}},
+ {{TOBN(0x5726e357, 0xd8a3c5cf), TOBN(0x1197ecc3, 0x2abb2b13),
+ TOBN(0x6c0d7f7f, 0x31ae88dd), TOBN(0x15b20d1a, 0xfdbb3efe)},
+ {TOBN(0xcd06aa26, 0x70584039), TOBN(0x2277c969, 0xa7dc9747),
+ TOBN(0xbca69587, 0x7855d815), TOBN(0x899ea238, 0x5188b32a)}},
+ {{TOBN(0x37d9228b, 0x760c1c9d), TOBN(0xc7efbb11, 0x9b5c18da),
+ TOBN(0x7f0d1bc8, 0x19f6dbc5), TOBN(0x4875384b, 0x07e6905b)},
+ {TOBN(0xc7c50baa, 0x3ba8cd86), TOBN(0xb0ce40fb, 0xc2905de0),
+ TOBN(0x70840673, 0x7a231952), TOBN(0xa912a262, 0xcf43de26)}},
+ {{TOBN(0x9c38ddcc, 0xeb5b76c1), TOBN(0x746f5285, 0x26fc0ab4),
+ TOBN(0x52a63a50, 0xd62c269f), TOBN(0x60049c55, 0x99458621)},
+ {TOBN(0xe7f48f82, 0x3c2f7c9e), TOBN(0x6bd99043, 0x917d5cf3),
+ TOBN(0xeb1317a8, 0x8701f469), TOBN(0xbd3fe2ed, 0x9a449fe0)}},
+ {{TOBN(0x421e79ca, 0x12ef3d36), TOBN(0x9ee3c36c, 0x3e7ea5de),
+ TOBN(0xe48198b5, 0xcdff36f7), TOBN(0xaff4f967, 0xc6b82228)},
+ {TOBN(0x15e19dd0, 0xc47adb7e), TOBN(0x45699b23, 0x032e7dfa),
+ TOBN(0x40680c8b, 0x1fae026a), TOBN(0x5a347a48, 0x550dbf4d)}},
+ {{TOBN(0xe652533b, 0x3cef0d7d), TOBN(0xd94f7b18, 0x2bbb4381),
+ TOBN(0x838752be, 0x0e80f500), TOBN(0x8e6e2488, 0x9e9c9bfb)},
+ {TOBN(0xc9751697, 0x16caca6a), TOBN(0x866c49d8, 0x38531ad9),
+ TOBN(0xc917e239, 0x7151ade1), TOBN(0x2d016ec1, 0x6037c407)}},
+ {{TOBN(0xa407ccc9, 0x00eac3f9), TOBN(0x835f6280, 0xe2ed4748),
+ TOBN(0xcc54c347, 0x1cc98e0d), TOBN(0x0e969937, 0xdcb572eb)},
+ {TOBN(0x1b16c8e8, 0x8f30c9cb), TOBN(0xa606ae75, 0x373c4661),
+ TOBN(0x47aa689b, 0x35502cab), TOBN(0xf89014ae, 0x4d9bb64f)}},
+ {{TOBN(0x202f6a9c, 0x31c71f7b), TOBN(0x01f95aa3, 0x296ffe5c),
+ TOBN(0x5fc06014, 0x53cec3a3), TOBN(0xeb991237, 0x5f498a45)},
+ {TOBN(0xae9a935e, 0x5d91ba87), TOBN(0xc6ac6281, 0x0b564a19),
+ TOBN(0x8a8fe81c, 0x3bd44e69), TOBN(0x7c8b467f, 0x9dd11d45)}},
+ {{TOBN(0xf772251f, 0xea5b8e69), TOBN(0xaeecb3bd, 0xc5b75fbc),
+ TOBN(0x1aca3331, 0x887ff0e5), TOBN(0xbe5d49ff, 0x19f0a131)},
+ {TOBN(0x582c13aa, 0xe5c8646f), TOBN(0xdbaa12e8, 0x20e19980),
+ TOBN(0x8f40f31a, 0xf7abbd94), TOBN(0x1f13f5a8, 0x1dfc7663)}},
+ {{TOBN(0x5d81f1ee, 0xaceb4fc0), TOBN(0x36256002, 0x5e6f0f42),
+ TOBN(0x4b67d6d7, 0x751370c8), TOBN(0x2608b698, 0x03e80589)},
+ {TOBN(0xcfc0d2fc, 0x05268301), TOBN(0xa6943d39, 0x40309212),
+ TOBN(0x192a90c2, 0x1fd0e1c2), TOBN(0xb209f113, 0x37f1dc76)}},
+ {{TOBN(0xefcc5e06, 0x97bf1298), TOBN(0xcbdb6730, 0x219d639e),
+ TOBN(0xd009c116, 0xb81e8c6f), TOBN(0xa3ffdde3, 0x1a7ce2e5)},
+ {TOBN(0xc53fbaaa, 0xa914d3ba), TOBN(0x836d500f, 0x88df85ee),
+ TOBN(0xd98dc71b, 0x66ee0751), TOBN(0x5a3d7005, 0x714516fd)}},
+ {{TOBN(0x21d3634d, 0x39eedbba), TOBN(0x35cd2e68, 0x0455a46d),
+ TOBN(0xc8cafe65, 0xf9d7eb0c), TOBN(0xbda3ce9e, 0x00cefb3e)},
+ {TOBN(0xddc17a60, 0x2c9cf7a4), TOBN(0x01572ee4, 0x7bcb8773),
+ TOBN(0xa92b2b01, 0x8c7548df), TOBN(0x732fd309, 0xa84600e3)}},
+ {{TOBN(0xe22109c7, 0x16543a40), TOBN(0x9acafd36, 0xfede3c6c),
+ TOBN(0xfb206852, 0x6824e614), TOBN(0x2a4544a9, 0xda25dca0)},
+ {TOBN(0x25985262, 0x91d60b06), TOBN(0x281b7be9, 0x28753545),
+ TOBN(0xec667b1a, 0x90f13b27), TOBN(0x33a83aff, 0x940e2eb4)}},
+ {{TOBN(0x80009862, 0xd5d721d5), TOBN(0x0c3357a3, 0x5bd3a182),
+ TOBN(0x27f3a83b, 0x7aa2cda4), TOBN(0xb58ae74e, 0xf6f83085)},
+ {TOBN(0x2a911a81, 0x2e6dad6b), TOBN(0xde286051, 0xf43d6c5b),
+ TOBN(0x4bdccc41, 0xf996c4d8), TOBN(0xe7312ec0, 0x0ae1e24e)}}},
+ {{{TOBN(0xf8d112e7, 0x6e6485b3), TOBN(0x4d3e24db, 0x771c52f8),
+ TOBN(0x48e3ee41, 0x684a2f6d), TOBN(0x7161957d, 0x21d95551)},
+ {TOBN(0x19631283, 0xcdb12a6c), TOBN(0xbf3fa882, 0x2e50e164),
+ TOBN(0xf6254b63, 0x3166cc73), TOBN(0x3aefa7ae, 0xaee8cc38)}},
+ {{TOBN(0x79b0fe62, 0x3b36f9fd), TOBN(0x26543b23, 0xfde19fc0),
+ TOBN(0x136e64a0, 0x958482ef), TOBN(0x23f63771, 0x9b095825)},
+ {TOBN(0x14cfd596, 0xb6a1142e), TOBN(0x5ea6aac6, 0x335aac0b),
+ TOBN(0x86a0e8bd, 0xf3081dd5), TOBN(0x5fb89d79, 0x003dc12a)}},
+ {{TOBN(0xf615c33a, 0xf72e34d4), TOBN(0x0bd9ea40, 0x110eec35),
+ TOBN(0x1c12bc5b, 0xc1dea34e), TOBN(0x686584c9, 0x49ae4699)},
+ {TOBN(0x13ad95d3, 0x8c97b942), TOBN(0x4609561a, 0x4e5c7562),
+ TOBN(0x9e94a4ae, 0xf2737f89), TOBN(0xf57594c6, 0x371c78b6)}},
+ {{TOBN(0x0f0165fc, 0xe3779ee3), TOBN(0xe00e7f9d, 0xbd495d9e),
+ TOBN(0x1fa4efa2, 0x20284e7a), TOBN(0x4564bade, 0x47ac6219)},
+ {TOBN(0x90e6312a, 0xc4708e8e), TOBN(0x4f5725fb, 0xa71e9adf),
+ TOBN(0xe95f55ae, 0x3d684b9f), TOBN(0x47f7ccb1, 0x1e94b415)}},
+ {{TOBN(0x7322851b, 0x8d946581), TOBN(0xf0d13133, 0xbdf4a012),
+ TOBN(0xa3510f69, 0x6584dae0), TOBN(0x03a7c171, 0x3c9f6c6d)},
+ {TOBN(0x5be97f38, 0xe475381a), TOBN(0xca1ba422, 0x85823334),
+ TOBN(0xf83cc5c7, 0x0be17dda), TOBN(0x158b1494, 0x0b918c0f)}},
+ {{TOBN(0xda3a77e5, 0x522e6b69), TOBN(0x69c908c3, 0xbbcd6c18),
+ TOBN(0x1f1b9e48, 0xd924fd56), TOBN(0x37c64e36, 0xaa4bb3f7)},
+ {TOBN(0x5a4fdbdf, 0xee478d7d), TOBN(0xba75c8bc, 0x0193f7a0),
+ TOBN(0x84bc1e84, 0x56cd16df), TOBN(0x1fb08f08, 0x46fad151)}},
+ {{TOBN(0x8a7cabf9, 0x842e9f30), TOBN(0xa331d4bf, 0x5eab83af),
+ TOBN(0xd272cfba, 0x017f2a6a), TOBN(0x27560abc, 0x83aba0e3)},
+ {TOBN(0x94b83387, 0x0e3a6b75), TOBN(0x25c6aea2, 0x6b9f50f5),
+ TOBN(0x803d691d, 0xb5fdf6d0), TOBN(0x03b77509, 0xe6333514)}},
+ {{TOBN(0x36178903, 0x61a341c1), TOBN(0x3604dc60, 0x0cfd6142),
+ TOBN(0x022295eb, 0x8533316c), TOBN(0x3dbde4ac, 0x44af2922)},
+ {TOBN(0x898afc5d, 0x1c7eef69), TOBN(0x58896805, 0xd14f4fa1),
+ TOBN(0x05002160, 0x203c21ca), TOBN(0x6f0d1f30, 0x40ef730b)}},
+ {{TOBN(0x8e8c44d4, 0x196224f8), TOBN(0x75a4ab95, 0x374d079d),
+ TOBN(0x79085ecc, 0x7d48f123), TOBN(0x56f04d31, 0x1bf65ad8)},
+ {TOBN(0xe220bf1c, 0xbda602b2), TOBN(0x73ee1742, 0xf9612c69),
+ TOBN(0x76008fc8, 0x084fd06b), TOBN(0x4000ef9f, 0xf11380d1)}},
+ {{TOBN(0x48201b4b, 0x12cfe297), TOBN(0x3eee129c, 0x292f74e5),
+ TOBN(0xe1fe114e, 0xc9e874e8), TOBN(0x899b055c, 0x92c5fc41)},
+ {TOBN(0x4e477a64, 0x3a39c8cf), TOBN(0x82f09efe, 0x78963cc9),
+ TOBN(0x6fd3fd8f, 0xd333f863), TOBN(0x85132b2a, 0xdc949c63)}},
+ {{TOBN(0x7e06a3ab, 0x516eb17b), TOBN(0x73bec06f, 0xd2c7372b),
+ TOBN(0xe4f74f55, 0xba896da6), TOBN(0xbb4afef8, 0x8e9eb40f)},
+ {TOBN(0x2d75bec8, 0xe61d66b0), TOBN(0x02bda4b4, 0xef29300b),
+ TOBN(0x8bbaa8de, 0x026baa5a), TOBN(0xff54befd, 0xa07f4440)}},
+ {{TOBN(0xbd9b8b1d, 0xbe7a2af3), TOBN(0xec51caa9, 0x4fb74a72),
+ TOBN(0xb9937a4b, 0x63879697), TOBN(0x7c9a9d20, 0xec2687d5)},
+ {TOBN(0x1773e44f, 0x6ef5f014), TOBN(0x8abcf412, 0xe90c6900),
+ TOBN(0x387bd022, 0x8142161e), TOBN(0x50393755, 0xfcb6ff2a)}},
+ {{TOBN(0x9813fd56, 0xed6def63), TOBN(0x53cf6482, 0x7d53106c),
+ TOBN(0x991a35bd, 0x431f7ac1), TOBN(0xf1e274dd, 0x63e65faf)},
+ {TOBN(0xf63ffa3c, 0x44cc7880), TOBN(0x411a426b, 0x7c256981),
+ TOBN(0xb698b9fd, 0x93a420e0), TOBN(0x89fdddc0, 0xae53f8fe)}},
+ {{TOBN(0x766e0722, 0x32398baa), TOBN(0x205fee42, 0x5cfca031),
+ TOBN(0xa49f5341, 0x7a029cf2), TOBN(0xa88c68b8, 0x4023890d)},
+ {TOBN(0xbc275041, 0x7337aaa8), TOBN(0x9ed364ad, 0x0eb384f4),
+ TOBN(0xe0816f85, 0x29aba92f), TOBN(0x2e9e1941, 0x04e38a88)}},
+ {{TOBN(0x57eef44a, 0x3dafd2d5), TOBN(0x35d1fae5, 0x97ed98d8),
+ TOBN(0x50628c09, 0x2307f9b1), TOBN(0x09d84aae, 0xd6cba5c6)},
+ {TOBN(0x67071bc7, 0x88aaa691), TOBN(0x2dea57a9, 0xafe6cb03),
+ TOBN(0xdfe11bb4, 0x3d78ac01), TOBN(0x7286418c, 0x7fd7aa51)}},
+ {{TOBN(0xfabf7709, 0x77f7195a), TOBN(0x8ec86167, 0xadeb838f),
+ TOBN(0xea1285a8, 0xbb4f012d), TOBN(0xd6883503, 0x9a3eab3f)},
+ {TOBN(0xee5d24f8, 0x309004c2), TOBN(0xa96e4b76, 0x13ffe95e),
+ TOBN(0x0cdffe12, 0xbd223ea4), TOBN(0x8f5c2ee5, 0xb6739a53)}},
+ {{TOBN(0x5cb4aaa5, 0xdd968198), TOBN(0xfa131c52, 0x72413a6c),
+ TOBN(0x53d46a90, 0x9536d903), TOBN(0xb270f0d3, 0x48606d8e)},
+ {TOBN(0x518c7564, 0xa053a3bc), TOBN(0x088254b7, 0x1a86caef),
+ TOBN(0xb3ba8cb4, 0x0ab5efd0), TOBN(0x5c59900e, 0x4605945d)}},
+ {{TOBN(0xecace1dd, 0xa1887395), TOBN(0x40960f36, 0x932a65de),
+ TOBN(0x9611ff5c, 0x3aa95529), TOBN(0xc58215b0, 0x7c1e5a36)},
+ {TOBN(0xd48c9b58, 0xf0e1a524), TOBN(0xb406856b, 0xf590dfb8),
+ TOBN(0xc7605e04, 0x9cd95662), TOBN(0x0dd036ee, 0xa33ecf82)}},
+ {{TOBN(0xa50171ac, 0xc33156b3), TOBN(0xf09d24ea, 0x4a80172e),
+ TOBN(0x4e1f72c6, 0x76dc8eef), TOBN(0xe60caadc, 0x5e3d44ee)},
+ {TOBN(0x006ef8a6, 0x979b1d8f), TOBN(0x60908a1c, 0x97788d26),
+ TOBN(0x6e08f95b, 0x266feec0), TOBN(0x618427c2, 0x22e8c94e)}},
+ {{TOBN(0x3d613339, 0x59145a65), TOBN(0xcd9bc368, 0xfa406337),
+ TOBN(0x82d11be3, 0x2d8a52a0), TOBN(0xf6877b27, 0x97a1c590)},
+ {TOBN(0x837a819b, 0xf5cbdb25), TOBN(0x2a4fd1d8, 0xde090249),
+ TOBN(0x622a7de7, 0x74990e5f), TOBN(0x840fa5a0, 0x7945511b)}},
+ {{TOBN(0x30b974be, 0x6558842d), TOBN(0x70df8c64, 0x17f3d0a6),
+ TOBN(0x7c803520, 0x7542e46d), TOBN(0x7251fe7f, 0xe4ecc823)},
+ {TOBN(0xe59134cb, 0x5e9aac9a), TOBN(0x11bb0934, 0xf0045d71),
+ TOBN(0x53e5d9b5, 0xdbcb1d4e), TOBN(0x8d97a905, 0x92defc91)}},
+ {{TOBN(0xfe289327, 0x7946d3f9), TOBN(0xe132bd24, 0x07472273),
+ TOBN(0xeeeb510c, 0x1eb6ae86), TOBN(0x777708c5, 0xf0595067)},
+ {TOBN(0x18e2c8cd, 0x1297029e), TOBN(0x2c61095c, 0xbbf9305e),
+ TOBN(0xe466c258, 0x6b85d6d9), TOBN(0x8ac06c36, 0xda1ea530)}},
+ {{TOBN(0xa365dc39, 0xa1304668), TOBN(0xe4a9c885, 0x07f89606),
+ TOBN(0x65a4898f, 0xacc7228d), TOBN(0x3e2347ff, 0x84ca8303)},
+ {TOBN(0xa5f6fb77, 0xea7d23a3), TOBN(0x2fac257d, 0x672a71cd),
+ TOBN(0x6908bef8, 0x7e6a44d3), TOBN(0x8ff87566, 0x891d3d7a)}},
+ {{TOBN(0xe58e90b3, 0x6b0cf82e), TOBN(0x6438d246, 0x2615b5e7),
+ TOBN(0x07b1f8fc, 0x669c145a), TOBN(0xb0d8b2da, 0x36f1e1cb)},
+ {TOBN(0x54d5dadb, 0xd9184c4d), TOBN(0x3dbb18d5, 0xf93d9976),
+ TOBN(0x0a3e0f56, 0xd1147d47), TOBN(0x2afa8c8d, 0xa0a48609)}},
+ {{TOBN(0x275353e8, 0xbc36742c), TOBN(0x898f427e, 0xeea0ed90),
+ TOBN(0x26f4947e, 0x3e477b00), TOBN(0x8ad8848a, 0x308741e3)},
+ {TOBN(0x6c703c38, 0xd74a2a46), TOBN(0x5e3e05a9, 0x9ba17ba2),
+ TOBN(0xc1fa6f66, 0x4ab9a9e4), TOBN(0x474a2d9a, 0x3841d6ec)}},
+ {{TOBN(0x871239ad, 0x653ae326), TOBN(0x14bcf72a, 0xa74cbb43),
+ TOBN(0x8737650e, 0x20d4c083), TOBN(0x3df86536, 0x110ed4af)},
+ {TOBN(0xd2d86fe7, 0xb53ca555), TOBN(0x688cb00d, 0xabd5d538),
+ TOBN(0xcf81bda3, 0x1ad38468), TOBN(0x7ccfe3cc, 0xf01167b6)}},
+ {{TOBN(0xcf4f47e0, 0x6c4c1fe6), TOBN(0x557e1f1a, 0x298bbb79),
+ TOBN(0xf93b974f, 0x30d45a14), TOBN(0x174a1d2d, 0x0baf97c4)},
+ {TOBN(0x7a003b30, 0xc51fbf53), TOBN(0xd8940991, 0xee68b225),
+ TOBN(0x5b0aa7b7, 0x1c0f4173), TOBN(0x975797c9, 0xa20a7153)}},
+ {{TOBN(0x26e08c07, 0xe3533d77), TOBN(0xd7222e6a, 0x2e341c99),
+ TOBN(0x9d60ec3d, 0x8d2dc4ed), TOBN(0xbdfe0d8f, 0x7c476cf8)},
+ {TOBN(0x1fe59ab6, 0x1d056605), TOBN(0xa9ea9df6, 0x86a8551f),
+ TOBN(0x8489941e, 0x47fb8d8c), TOBN(0xfeb874eb, 0x4a7f1b10)}},
+ {{TOBN(0xfe5fea86, 0x7ee0d98f), TOBN(0x201ad34b, 0xdbf61864),
+ TOBN(0x45d8fe47, 0x37c031d4), TOBN(0xd5f49fae, 0x795f0822)},
+ {TOBN(0xdb0fb291, 0xc7f4a40c), TOBN(0x2e69d9c1, 0x730ddd92),
+ TOBN(0x754e1054, 0x49d76987), TOBN(0x8a24911d, 0x7662db87)}},
+ {{TOBN(0x61fc1810, 0x60a71676), TOBN(0xe852d1a8, 0xf66a8ad1),
+ TOBN(0x172bbd65, 0x6417231e), TOBN(0x0d6de7bd, 0x3babb11f)},
+ {TOBN(0x6fde6f88, 0xc8e347f8), TOBN(0x1c587547, 0x9bd99cc3),
+ TOBN(0x78e54ed0, 0x34076950), TOBN(0x97f0f334, 0x796e83ba)}},
+ {{TOBN(0xe4dbe1ce, 0x4924867a), TOBN(0xbd5f51b0, 0x60b84917),
+ TOBN(0x37530040, 0x3cb09a79), TOBN(0xdb3fe0f8, 0xff1743d8)},
+ {TOBN(0xed7894d8, 0x556fa9db), TOBN(0xfa262169, 0x23412fbf),
+ TOBN(0x563be0db, 0xba7b9291), TOBN(0x6ca8b8c0, 0x0c9fb234)}},
+ {{TOBN(0xed406aa9, 0xbd763802), TOBN(0xc21486a0, 0x65303da1),
+ TOBN(0x61ae291e, 0xc7e62ec4), TOBN(0x622a0492, 0xdf99333e)},
+ {TOBN(0x7fd80c9d, 0xbb7a8ee0), TOBN(0xdc2ed3bc, 0x6c01aedb),
+ TOBN(0x35c35a12, 0x08be74ec), TOBN(0xd540cb1a, 0x469f671f)}},
+ {{TOBN(0xd16ced4e, 0xcf84f6c7), TOBN(0x8561fb9c, 0x2d090f43),
+ TOBN(0x7e693d79, 0x6f239db4), TOBN(0xa736f928, 0x77bd0d94)},
+ {TOBN(0x07b4d929, 0x2c1950ee), TOBN(0xda177543, 0x56dc11b3),
+ TOBN(0xa5dfbbaa, 0x7a6a878e), TOBN(0x1c70cb29, 0x4decb08a)}},
+ {{TOBN(0xfba28c8b, 0x6f0f7c50), TOBN(0xa8eba2b8, 0x854dcc6d),
+ TOBN(0x5ff8e89a, 0x36b78642), TOBN(0x070c1c8e, 0xf6873adf)},
+ {TOBN(0xbbd3c371, 0x6484d2e4), TOBN(0xfb78318f, 0x0d414129),
+ TOBN(0x2621a39c, 0x6ad93b0b), TOBN(0x979d74c2, 0xa9e917f7)}},
+ {{TOBN(0xfc195647, 0x61fb0428), TOBN(0x4d78954a, 0xbee624d4),
+ TOBN(0xb94896e0, 0xb8ae86fd), TOBN(0x6667ac0c, 0xc91c8b13)},
+ {TOBN(0x9f180512, 0x43bcf832), TOBN(0xfbadf8b7, 0xa0010137),
+ TOBN(0xc69b4089, 0xb3ba8aa7), TOBN(0xfac4bacd, 0xe687ce85)}},
+ {{TOBN(0x9164088d, 0x977eab40), TOBN(0x51f4c5b6, 0x2760b390),
+ TOBN(0xd238238f, 0x340dd553), TOBN(0x358566c3, 0xdb1d31c9)},
+ {TOBN(0x3a5ad69e, 0x5068f5ff), TOBN(0xf31435fc, 0xdaff6b06),
+ TOBN(0xae549a5b, 0xd6debff0), TOBN(0x59e5f0b7, 0x75e01331)}},
+ {{TOBN(0x5d492fb8, 0x98559acf), TOBN(0x96018c2e, 0x4db79b50),
+ TOBN(0x55f4a48f, 0x609f66aa), TOBN(0x1943b3af, 0x4900a14f)},
+ {TOBN(0xc22496df, 0x15a40d39), TOBN(0xb2a44684, 0x4c20f7c5),
+ TOBN(0x76a35afa, 0x3b98404c), TOBN(0xbec75725, 0xff5d1b77)}},
+ {{TOBN(0xb67aa163, 0xbea06444), TOBN(0x27e95bb2, 0xf724b6f2),
+ TOBN(0x3c20e3e9, 0xd238c8ab), TOBN(0x1213754e, 0xddd6ae17)},
+ {TOBN(0x8c431020, 0x716e0f74), TOBN(0x6679c82e, 0xffc095c2),
+ TOBN(0x2eb3adf4, 0xd0ac2932), TOBN(0x2cc970d3, 0x01bb7a76)}},
+ {{TOBN(0x70c71f2f, 0x740f0e66), TOBN(0x545c616b, 0x2b6b23cc),
+ TOBN(0x4528cfcb, 0xb40a8bd7), TOBN(0xff839633, 0x2ab27722)},
+ {TOBN(0x049127d9, 0x025ac99a), TOBN(0xd314d4a0, 0x2b63e33b),
+ TOBN(0xc8c310e7, 0x28d84519), TOBN(0x0fcb8983, 0xb3bc84ba)}},
+ {{TOBN(0x2cc52261, 0x38634818), TOBN(0x501814f4, 0xb44c2e0b),
+ TOBN(0xf7e181aa, 0x54dfdba3), TOBN(0xcfd58ff0, 0xe759718c)},
+ {TOBN(0xf90cdb14, 0xd3b507a8), TOBN(0x57bd478e, 0xc50bdad8),
+ TOBN(0x29c197e2, 0x50e5f9aa), TOBN(0x4db6eef8, 0xe40bc855)}},
+ {{TOBN(0x2cc8f21a, 0xd1fc0654), TOBN(0xc71cc963, 0x81269d73),
+ TOBN(0xecfbb204, 0x077f49f9), TOBN(0xdde92571, 0xca56b793)},
+ {TOBN(0x9abed6a3, 0xf97ad8f7), TOBN(0xe6c19d3f, 0x924de3bd),
+ TOBN(0x8dce92f4, 0xa140a800), TOBN(0x85f44d1e, 0x1337af07)}},
+ {{TOBN(0x5953c08b, 0x09d64c52), TOBN(0xa1b5e49f, 0xf5df9749),
+ TOBN(0x336a8fb8, 0x52735f7d), TOBN(0xb332b6db, 0x9add676b)},
+ {TOBN(0x558b88a0, 0xb4511aa4), TOBN(0x09788752, 0xdbd5cc55),
+ TOBN(0x16b43b9c, 0xd8cd52bd), TOBN(0x7f0bc5a0, 0xc2a2696b)}},
+ {{TOBN(0x146e12d4, 0xc11f61ef), TOBN(0x9ce10754, 0x3a83e79e),
+ TOBN(0x08ec73d9, 0x6cbfca15), TOBN(0x09ff29ad, 0x5b49653f)},
+ {TOBN(0xe31b72bd, 0xe7da946e), TOBN(0xebf9eb3b, 0xee80a4f2),
+ TOBN(0xd1aabd08, 0x17598ce4), TOBN(0x18b5fef4, 0x53f37e80)}},
+ {{TOBN(0xd5d5cdd3, 0x5958cd79), TOBN(0x3580a1b5, 0x1d373114),
+ TOBN(0xa36e4c91, 0xfa935726), TOBN(0xa38c534d, 0xef20d760)},
+ {TOBN(0x7088e40a, 0x2ff5845b), TOBN(0xe5bb40bd, 0xbd78177f),
+ TOBN(0x4f06a7a8, 0x857f9920), TOBN(0xe3cc3e50, 0xe968f05d)}},
+ {{TOBN(0x1d68b7fe, 0xe5682d26), TOBN(0x5206f76f, 0xaec7f87c),
+ TOBN(0x41110530, 0x041951ab), TOBN(0x58ec52c1, 0xd4b5a71a)},
+ {TOBN(0xf3488f99, 0x0f75cf9a), TOBN(0xf411951f, 0xba82d0d5),
+ TOBN(0x27ee75be, 0x618895ab), TOBN(0xeae060d4, 0x6d8aab14)}},
+ {{TOBN(0x9ae1df73, 0x7fb54dc2), TOBN(0x1f3e391b, 0x25963649),
+ TOBN(0x242ec32a, 0xfe055081), TOBN(0x5bd450ef, 0x8491c9bd)},
+ {TOBN(0x367efc67, 0x981eb389), TOBN(0xed7e1928, 0x3a0550d5),
+ TOBN(0x362e776b, 0xab3ce75c), TOBN(0xe890e308, 0x1f24c523)}},
+ {{TOBN(0xb961b682, 0xfeccef76), TOBN(0x8b8e11f5, 0x8bba6d92),
+ TOBN(0x8f2ccc4c, 0x2b2375c4), TOBN(0x0d7f7a52, 0xe2f86cfa)},
+ {TOBN(0xfd94d30a, 0x9efe5633), TOBN(0x2d8d246b, 0x5451f934),
+ TOBN(0x2234c6e3, 0x244e6a00), TOBN(0xde2b5b0d, 0xddec8c50)}},
+ {{TOBN(0x2ce53c5a, 0xbf776f5b), TOBN(0x6f724071, 0x60357b05),
+ TOBN(0xb2593717, 0x71bf3f7a), TOBN(0x87d2501c, 0x440c4a9f)},
+ {TOBN(0x440552e1, 0x87b05340), TOBN(0xb7bf7cc8, 0x21624c32),
+ TOBN(0x4155a6ce, 0x22facddb), TOBN(0x5a4228cb, 0x889837ef)}},
+ {{TOBN(0xef87d6d6, 0xfd4fd671), TOBN(0xa233687e, 0xc2daa10e),
+ TOBN(0x75622244, 0x03c0eb96), TOBN(0x7632d184, 0x8bf19be6)},
+ {TOBN(0x05d0f8e9, 0x40735ff4), TOBN(0x3a3e6e13, 0xc00931f1),
+ TOBN(0x31ccde6a, 0xdafe3f18), TOBN(0xf381366a, 0xcfe51207)}},
+ {{TOBN(0x24c222a9, 0x60167d92), TOBN(0x62f9d6f8, 0x7529f18c),
+ TOBN(0x412397c0, 0x0353b114), TOBN(0x334d89dc, 0xef808043)},
+ {TOBN(0xd9ec63ba, 0x2a4383ce), TOBN(0xcec8e937, 0x5cf92ba0),
+ TOBN(0xfb8b4288, 0xc8be74c0), TOBN(0x67d6912f, 0x105d4391)}},
+ {{TOBN(0x7b996c46, 0x1b913149), TOBN(0x36aae2ef, 0x3a4e02da),
+ TOBN(0xb68aa003, 0x972de594), TOBN(0x284ec70d, 0x4ec6d545)},
+ {TOBN(0xf3d2b2d0, 0x61391d54), TOBN(0x69c5d5d6, 0xfe114e92),
+ TOBN(0xbe0f00b5, 0xb4482dff), TOBN(0xe1596fa5, 0xf5bf33c5)}},
+ {{TOBN(0x10595b56, 0x96a71cba), TOBN(0x944938b2, 0xfdcadeb7),
+ TOBN(0xa282da4c, 0xfccd8471), TOBN(0x98ec05f3, 0x0d37bfe1)},
+ {TOBN(0xe171ce1b, 0x0698304a), TOBN(0x2d691444, 0x21bdf79b),
+ TOBN(0xd0cd3b74, 0x1b21dec1), TOBN(0x712ecd8b, 0x16a15f71)}},
+ {{TOBN(0x8d4c00a7, 0x00fd56e1), TOBN(0x02ec9692, 0xf9527c18),
+ TOBN(0x21c44937, 0x4a3e42e1), TOBN(0x9176fbab, 0x1392ae0a)},
+ {TOBN(0x8726f1ba, 0x44b7b618), TOBN(0xb4d7aae9, 0xf1de491c),
+ TOBN(0xf91df7b9, 0x07b582c0), TOBN(0x7e116c30, 0xef60aa3a)}},
+ {{TOBN(0x99270f81, 0x466265d7), TOBN(0xb15b6fe2, 0x4df7adf0),
+ TOBN(0xfe33b2d3, 0xf9738f7f), TOBN(0x48553ab9, 0xd6d70f95)},
+ {TOBN(0x2cc72ac8, 0xc21e94db), TOBN(0x795ac38d, 0xbdc0bbee),
+ TOBN(0x0a1be449, 0x2e40478f), TOBN(0x81bd3394, 0x052bde55)}},
+ {{TOBN(0x63c8dbe9, 0x56b3c4f2), TOBN(0x017a99cf, 0x904177cc),
+ TOBN(0x947bbddb, 0x4d010fc1), TOBN(0xacf9b00b, 0xbb2c9b21)},
+ {TOBN(0x2970bc8d, 0x47173611), TOBN(0x1a4cbe08, 0xac7d756f),
+ TOBN(0x06d9f4aa, 0x67d541a2), TOBN(0xa3e8b689, 0x59c2cf44)}},
+ {{TOBN(0xaad066da, 0x4d88f1dd), TOBN(0xc604f165, 0x7ad35dea),
+ TOBN(0x7edc0720, 0x4478ca67), TOBN(0xa10dfae0, 0xba02ce06)},
+ {TOBN(0xeceb1c76, 0xaf36f4e4), TOBN(0x994b2292, 0xaf3f8f48),
+ TOBN(0xbf9ed77b, 0x77c8a68c), TOBN(0x74f544ea, 0x51744c9d)}},
+ {{TOBN(0x82d05bb9, 0x8113a757), TOBN(0x4ef2d2b4, 0x8a9885e4),
+ TOBN(0x1e332be5, 0x1aa7865f), TOBN(0x22b76b18, 0x290d1a52)},
+ {TOBN(0x308a2310, 0x44351683), TOBN(0x9d861896, 0xa3f22840),
+ TOBN(0x5959ddcd, 0x841ed947), TOBN(0x0def0c94, 0x154b73bf)}},
+ {{TOBN(0xf0105417, 0x4c7c15e0), TOBN(0x539bfb02, 0x3a277c32),
+ TOBN(0xe699268e, 0xf9dccf5f), TOBN(0x9f5796a5, 0x0247a3bd)},
+ {TOBN(0x8b839de8, 0x4f157269), TOBN(0xc825c1e5, 0x7a30196b),
+ TOBN(0x6ef0aabc, 0xdc8a5a91), TOBN(0xf4a8ce6c, 0x498b7fe6)}},
+ {{TOBN(0x1cce35a7, 0x70cbac78), TOBN(0x83488e9b, 0xf6b23958),
+ TOBN(0x0341a070, 0xd76cb011), TOBN(0xda6c9d06, 0xae1b2658)},
+ {TOBN(0xb701fb30, 0xdd648c52), TOBN(0x994ca02c, 0x52fb9fd1),
+ TOBN(0x06933117, 0x6f563086), TOBN(0x3d2b8100, 0x17856bab)}},
+ {{TOBN(0xe89f48c8, 0x5963a46e), TOBN(0x658ab875, 0xa99e61c7),
+ TOBN(0x6e296f87, 0x4b8517b4), TOBN(0x36c4fcdc, 0xfc1bc656)},
+ {TOBN(0xde5227a1, 0xa3906def), TOBN(0x9fe95f57, 0x62418945),
+ TOBN(0x20c91e81, 0xfdd96cde), TOBN(0x5adbe47e, 0xda4480de)}},
+ {{TOBN(0xa009370f, 0x396de2b6), TOBN(0x98583d4b, 0xf0ecc7bd),
+ TOBN(0xf44f6b57, 0xe51d0672), TOBN(0x03d6b078, 0x556b1984)},
+ {TOBN(0x27dbdd93, 0xb0b64912), TOBN(0x9b3a3434, 0x15687b09),
+ TOBN(0x0dba6461, 0x51ec20a9), TOBN(0xec93db7f, 0xff28187c)}},
+ {{TOBN(0x00ff8c24, 0x66e48bdd), TOBN(0x2514f2f9, 0x11ccd78e),
+ TOBN(0xeba11f4f, 0xe1250603), TOBN(0x8a22cd41, 0x243fa156)},
+ {TOBN(0xa4e58df4, 0xb283e4c6), TOBN(0x78c29859, 0x8b39783f),
+ TOBN(0x5235aee2, 0xa5259809), TOBN(0xc16284b5, 0x0e0227dd)}},
+ {{TOBN(0xa5f57916, 0x1338830d), TOBN(0x6d4b8a6b, 0xd2123fca),
+ TOBN(0x236ea68a, 0xf9c546f8), TOBN(0xc1d36873, 0xfa608d36)},
+ {TOBN(0xcd76e495, 0x8d436d13), TOBN(0xd4d9c221, 0x8fb080af),
+ TOBN(0x665c1728, 0xe8ad3fb5), TOBN(0xcf1ebe4d, 0xb3d572e0)}},
+ {{TOBN(0xa7a8746a, 0x584c5e20), TOBN(0x267e4ea1, 0xb9dc7035),
+ TOBN(0x593a15cf, 0xb9548c9b), TOBN(0x5e6e2135, 0x4bd012f3)},
+ {TOBN(0xdf31cc6a, 0x8c8f936e), TOBN(0x8af84d04, 0xb5c241dc),
+ TOBN(0x63990a6f, 0x345efb86), TOBN(0x6fef4e61, 0xb9b962cb)}}},
+ {{{TOBN(0xf6368f09, 0x25722608), TOBN(0x131260db, 0x131cf5c6),
+ TOBN(0x40eb353b, 0xfab4f7ac), TOBN(0x85c78880, 0x37eee829)},
+ {TOBN(0x4c1581ff, 0xc3bdf24e), TOBN(0x5bff75cb, 0xf5c3c5a8),
+ TOBN(0x35e8c83f, 0xa14e6f40), TOBN(0xb81d1c0f, 0x0295e0ca)}},
+ {{TOBN(0xfcde7cc8, 0xf43a730f), TOBN(0xe89b6f3c, 0x33ab590e),
+ TOBN(0xc823f529, 0xad03240b), TOBN(0x82b79afe, 0x98bea5db)},
+ {TOBN(0x568f2856, 0x962fe5de), TOBN(0x0c590adb, 0x60c591f3),
+ TOBN(0x1fc74a14, 0x4a28a858), TOBN(0x3b662498, 0xb3203f4c)}},
+ {{TOBN(0x91e3cf0d, 0x6c39765a), TOBN(0xa2db3acd, 0xac3cca0b),
+ TOBN(0x288f2f08, 0xcb953b50), TOBN(0x2414582c, 0xcf43cf1a)},
+ {TOBN(0x8dec8bbc, 0x60eee9a8), TOBN(0x54c79f02, 0x729aa042),
+ TOBN(0xd81cd5ec, 0x6532f5d5), TOBN(0xa672303a, 0xcf82e15f)}},
+ {{TOBN(0x376aafa8, 0x719c0563), TOBN(0xcd8ad2dc, 0xbc5fc79f),
+ TOBN(0x303fdb9f, 0xcb750cd3), TOBN(0x14ff052f, 0x4418b08e)},
+ {TOBN(0xf75084cf, 0x3e2d6520), TOBN(0x7ebdf0f8, 0x144ed509),
+ TOBN(0xf43bf0f2, 0xd3f25b98), TOBN(0x86ad71cf, 0xa354d837)}},
+ {{TOBN(0xb827fe92, 0x26f43572), TOBN(0xdfd3ab5b, 0x5d824758),
+ TOBN(0x315dd23a, 0x539094c1), TOBN(0x85c0e37a, 0x66623d68)},
+ {TOBN(0x575c7972, 0x7be19ae0), TOBN(0x616a3396, 0xdf0d36b5),
+ TOBN(0xa1ebb3c8, 0x26b1ff7e), TOBN(0x635b9485, 0x140ad453)}},
+ {{TOBN(0x92bf3cda, 0xda430c0b), TOBN(0x4702850e, 0x3a96dac6),
+ TOBN(0xc91cf0a5, 0x15ac326a), TOBN(0x95de4f49, 0xab8c25e4)},
+ {TOBN(0xb01bad09, 0xe265c17c), TOBN(0x24e45464, 0x087b3881),
+ TOBN(0xd43e583c, 0xe1fac5ca), TOBN(0xe17cb318, 0x6ead97a6)}},
+ {{TOBN(0x6cc39243, 0x74dcec46), TOBN(0x33cfc02d, 0x54c2b73f),
+ TOBN(0x82917844, 0xf26cd99c), TOBN(0x8819dd95, 0xd1773f89)},
+ {TOBN(0x09572aa6, 0x0871f427), TOBN(0x8e0cf365, 0xf6f01c34),
+ TOBN(0x7fa52988, 0xbff1f5af), TOBN(0x4eb357ea, 0xe75e8e50)}},
+ {{TOBN(0xd9d0c8c4, 0x868af75d), TOBN(0xd7325cff, 0x45c8c7ea),
+ TOBN(0xab471996, 0xcc81ecb0), TOBN(0xff5d55f3, 0x611824ed)},
+ {TOBN(0xbe314541, 0x1977a0ee), TOBN(0x5085c4c5, 0x722038c6),
+ TOBN(0x2d5335bf, 0xf94bb495), TOBN(0x894ad8a6, 0xc8e2a082)}},
+ {{TOBN(0x5c3e2341, 0xada35438), TOBN(0xf4a9fc89, 0x049b8c4e),
+ TOBN(0xbeeb355a, 0x9f17cf34), TOBN(0x3f311e0e, 0x6c91fe10)},
+ {TOBN(0xc2d20038, 0x92ab9891), TOBN(0x257bdcc1, 0x3e8ce9a9),
+ TOBN(0x1b2d9789, 0x88c53bee), TOBN(0x927ce89a, 0xcdba143a)}},
+ {{TOBN(0xb0a32cca, 0x523db280), TOBN(0x5c889f8a, 0x50d43783),
+ TOBN(0x503e04b3, 0x4897d16f), TOBN(0x8cdb6e78, 0x08f5f2e8)},
+ {TOBN(0x6ab91cf0, 0x179c8e74), TOBN(0xd8874e52, 0x48211d60),
+ TOBN(0xf948d4d5, 0xea851200), TOBN(0x4076d41e, 0xe6f9840a)}},
+ {{TOBN(0xc20e263c, 0x47b517ea), TOBN(0x79a448fd, 0x30685e5e),
+ TOBN(0xe55f6f78, 0xf90631a0), TOBN(0x88a790b1, 0xa79e6346)},
+ {TOBN(0x62160c7d, 0x80969fe8), TOBN(0x54f92fd4, 0x41491bb9),
+ TOBN(0xa6645c23, 0x5c957526), TOBN(0xf44cc5ae, 0xbea3ce7b)}},
+ {{TOBN(0xf7628327, 0x8b1e68b7), TOBN(0xc731ad7a, 0x303f29d3),
+ TOBN(0xfe5a9ca9, 0x57d03ecb), TOBN(0x96c0d50c, 0x41bc97a7)},
+ {TOBN(0xc4669fe7, 0x9b4f7f24), TOBN(0xfdd781d8, 0x3d9967ef),
+ TOBN(0x7892c7c3, 0x5d2c208d), TOBN(0x8bf64f7c, 0xae545cb3)}},
+ {{TOBN(0xc01f862c, 0x467be912), TOBN(0xf4c85ee9, 0xc73d30cc),
+ TOBN(0x1fa6f4be, 0x6ab83ec7), TOBN(0xa07a3c1c, 0x4e3e3cf9)},
+ {TOBN(0x87f8ef45, 0x0c00beb3), TOBN(0x30e2c2b3, 0x000d4c3e),
+ TOBN(0x1aa00b94, 0xfe08bf5b), TOBN(0x32c133aa, 0x9224ef52)}},
+ {{TOBN(0x38df16bb, 0x32e5685d), TOBN(0x68a9e069, 0x58e6f544),
+ TOBN(0x495aaff7, 0xcdc5ebc6), TOBN(0xf894a645, 0x378b135f)},
+ {TOBN(0xf316350a, 0x09e27ecf), TOBN(0xeced201e, 0x58f7179d),
+ TOBN(0x2eec273c, 0xe97861ba), TOBN(0x47ec2cae, 0xd693be2e)}},
+ {{TOBN(0xfa4c97c4, 0xf68367ce), TOBN(0xe4f47d0b, 0xbe5a5755),
+ TOBN(0x17de815d, 0xb298a979), TOBN(0xd7eca659, 0xc177dc7d)},
+ {TOBN(0x20fdbb71, 0x49ded0a3), TOBN(0x4cb2aad4, 0xfb34d3c5),
+ TOBN(0x2cf31d28, 0x60858a33), TOBN(0x3b6873ef, 0xa24aa40f)}},
+ {{TOBN(0x540234b2, 0x2c11bb37), TOBN(0x2d0366dd, 0xed4c74a3),
+ TOBN(0xf9a968da, 0xeec5f25d), TOBN(0x36601068, 0x67b63142)},
+ {TOBN(0x07cd6d2c, 0x68d7b6d4), TOBN(0xa8f74f09, 0x0c842942),
+ TOBN(0xe2751404, 0x7768b1ee), TOBN(0x4b5f7e89, 0xfe62aee4)}},
+ {{TOBN(0xc6a77177, 0x89070d26), TOBN(0xa1f28e4e, 0xdd1c8bc7),
+ TOBN(0xea5f4f06, 0x469e1f17), TOBN(0x78fc242a, 0xfbdb78e0)},
+ {TOBN(0xc9c7c592, 0x8b0588f1), TOBN(0xb6b7a0fd, 0x1535921e),
+ TOBN(0xcc5bdb91, 0xbde5ae35), TOBN(0xb42c485e, 0x12ff1864)}},
+ {{TOBN(0xa1113e13, 0xdbab98aa), TOBN(0xde9d469b, 0xa17b1024),
+ TOBN(0x23f48b37, 0xc0462d3a), TOBN(0x3752e537, 0x7c5c078d)},
+ {TOBN(0xe3a86add, 0x15544eb9), TOBN(0xf013aea7, 0x80fba279),
+ TOBN(0x8b5bb76c, 0xf22001b5), TOBN(0xe617ba14, 0xf02891ab)}},
+ {{TOBN(0xd39182a6, 0x936219d3), TOBN(0x5ce1f194, 0xae51cb19),
+ TOBN(0xc78f8598, 0xbf07a74c), TOBN(0x6d7158f2, 0x22cbf1bc)},
+ {TOBN(0x3b846b21, 0xe300ce18), TOBN(0x35fba630, 0x2d11275d),
+ TOBN(0x5fe25c36, 0xa0239b9b), TOBN(0xd8beb35d, 0xdf05d940)}},
+ {{TOBN(0x4db02bb0, 0x1f7e320d), TOBN(0x0641c364, 0x6da320ea),
+ TOBN(0x6d95fa5d, 0x821389a3), TOBN(0x92699748, 0x8fcd8e3d)},
+ {TOBN(0x316fef17, 0xceb6c143), TOBN(0x67fcb841, 0xd933762b),
+ TOBN(0xbb837e35, 0x118b17f8), TOBN(0x4b92552f, 0x9fd24821)}},
+ {{TOBN(0xae6bc70e, 0x46aca793), TOBN(0x1cf0b0e4, 0xe579311b),
+ TOBN(0x8dc631be, 0x5802f716), TOBN(0x099bdc6f, 0xbddbee4d)},
+ {TOBN(0xcc352bb2, 0x0caf8b05), TOBN(0xf74d505a, 0x72d63df2),
+ TOBN(0xb9876d4b, 0x91c4f408), TOBN(0x1ce18473, 0x9e229b2d)}},
+ {{TOBN(0x49507597, 0x83abdb4a), TOBN(0x850fbcb6, 0xdee84b18),
+ TOBN(0x6325236e, 0x609e67dc), TOBN(0x04d831d9, 0x9336c6d8)},
+ {TOBN(0x8deaae3b, 0xfa12d45d), TOBN(0xe425f8ce, 0x4746e246),
+ TOBN(0x8004c175, 0x24f5f31e), TOBN(0xaca16d8f, 0xad62c3b7)}},
+ {{TOBN(0x0dc15a6a, 0x9152f934), TOBN(0xf1235e5d, 0xed0e12c1),
+ TOBN(0xc33c06ec, 0xda477dac), TOBN(0x76be8732, 0xb2ea0006)},
+ {TOBN(0xcf3f7831, 0x0c0cd313), TOBN(0x3c524553, 0xa614260d),
+ TOBN(0x31a756f8, 0xcab22d15), TOBN(0x03ee10d1, 0x77827a20)}},
+ {{TOBN(0xd1e059b2, 0x1994ef20), TOBN(0x2a653b69, 0x638ae318),
+ TOBN(0x70d5eb58, 0x2f699010), TOBN(0x279739f7, 0x09f5f84a)},
+ {TOBN(0x5da4663c, 0x8b799336), TOBN(0xfdfdf14d, 0x203c37eb),
+ TOBN(0x32d8a9dc, 0xa1dbfb2d), TOBN(0xab40cff0, 0x77d48f9b)}},
+ {{TOBN(0xc018b383, 0xd20b42d5), TOBN(0xf9a810ef, 0x9f78845f),
+ TOBN(0x40af3753, 0xbdba9df0), TOBN(0xb90bdcfc, 0x131dfdf9)},
+ {TOBN(0x18720591, 0xf01ab782), TOBN(0xc823f211, 0x6af12a88),
+ TOBN(0xa51b80f3, 0x0dc14401), TOBN(0xde248f77, 0xfb2dfbe3)}},
+ {{TOBN(0xef5a44e5, 0x0cafe751), TOBN(0x73997c9c, 0xd4dcd221),
+ TOBN(0x32fd86d1, 0xde854024), TOBN(0xd5b53adc, 0xa09b84bb)},
+ {TOBN(0x008d7a11, 0xdcedd8d1), TOBN(0x406bd1c8, 0x74b32c84),
+ TOBN(0x5d4472ff, 0x05dde8b1), TOBN(0x2e25f2cd, 0xfce2b32f)}},
+ {{TOBN(0xbec0dd5e, 0x29dfc254), TOBN(0x4455fcf6, 0x2b98b267),
+ TOBN(0x0b4d43a5, 0xc72df2ad), TOBN(0xea70e6be, 0x48a75397)},
+ {TOBN(0x2aad6169, 0x5820f3bf), TOBN(0xf410d2dd, 0x9e37f68f),
+ TOBN(0x70fb7dba, 0x7be5ac83), TOBN(0x636bb645, 0x36ec3eec)}},
+ {{TOBN(0x27104ea3, 0x9754e21c), TOBN(0xbc87a3e6, 0x8d63c373),
+ TOBN(0x483351d7, 0x4109db9a), TOBN(0x0fa724e3, 0x60134da7)},
+ {TOBN(0x9ff44c29, 0xb0720b16), TOBN(0x2dd0cf13, 0x06aceead),
+ TOBN(0x5942758c, 0xe26929a6), TOBN(0x96c5db92, 0xb766a92b)}},
+ {{TOBN(0xcec7d4c0, 0x5f18395e), TOBN(0xd3f22744, 0x1f80d032),
+ TOBN(0x7a68b37a, 0xcb86075b), TOBN(0x074764dd, 0xafef92db)},
+ {TOBN(0xded1e950, 0x7bc7f389), TOBN(0xc580c850, 0xb9756460),
+ TOBN(0xaeeec2a4, 0x7da48157), TOBN(0x3f0b4e7f, 0x82c587b3)}},
+ {{TOBN(0x231c6de8, 0xa9f19c53), TOBN(0x5717bd73, 0x6974e34e),
+ TOBN(0xd9e1d216, 0xf1508fa9), TOBN(0x9f112361, 0xdadaa124)},
+ {TOBN(0x80145e31, 0x823b7348), TOBN(0x4dd8f0d5, 0xac634069),
+ TOBN(0xe3d82fc7, 0x2297c258), TOBN(0x276fcfee, 0x9cee7431)}},
+ {{TOBN(0x8eb61b5e, 0x2bc0aea9), TOBN(0x4f668fd5, 0xde329431),
+ TOBN(0x03a32ab1, 0x38e4b87e), TOBN(0xe1374517, 0x73d0ef0b)},
+ {TOBN(0x1a46f7e6, 0x853ac983), TOBN(0xc3bdf42e, 0x68e78a57),
+ TOBN(0xacf20785, 0x2ea96dd1), TOBN(0xa10649b9, 0xf1638460)}},
+ {{TOBN(0xf2369f0b, 0x879fbbed), TOBN(0x0ff0ae86, 0xda9d1869),
+ TOBN(0x5251d759, 0x56766f45), TOBN(0x4984d8c0, 0x2be8d0fc)},
+ {TOBN(0x7ecc95a6, 0xd21008f0), TOBN(0x29bd54a0, 0x3a1a1c49),
+ TOBN(0xab9828c5, 0xd26c50f3), TOBN(0x32c0087c, 0x51d0d251)}},
+ {{TOBN(0x9bac3ce6, 0x0c1cdb26), TOBN(0xcd94d947, 0x557ca205),
+ TOBN(0x1b1bd598, 0x9db1fdcd), TOBN(0x0eda0108, 0xa3d8b149)},
+ {TOBN(0x95066610, 0x56152fcc), TOBN(0xc2f037e6, 0xe7192b33),
+ TOBN(0xdeffb41a, 0xc92e05a4), TOBN(0x1105f6c2, 0xc2f6c62e)}},
+ {{TOBN(0x68e73500, 0x8733913c), TOBN(0xcce86163, 0x3f3adc40),
+ TOBN(0xf407a942, 0x38a278e9), TOBN(0xd13c1b9d, 0x2ab21292)},
+ {TOBN(0x93ed7ec7, 0x1c74cf5c), TOBN(0x8887dc48, 0xf1a4c1b4),
+ TOBN(0x3830ff30, 0x4b3a11f1), TOBN(0x358c5a3c, 0x58937cb6)}},
+ {{TOBN(0x027dc404, 0x89022829), TOBN(0x40e93977, 0x3b798f79),
+ TOBN(0x90ad3337, 0x38be6ead), TOBN(0x9c23f6bc, 0xf34c0a5d)},
+ {TOBN(0xd1711a35, 0xfbffd8bb), TOBN(0x60fcfb49, 0x1949d3dd),
+ TOBN(0x09c8ef4b, 0x7825d93a), TOBN(0x24233cff, 0xa0a8c968)}},
+ {{TOBN(0x67ade46c, 0xe6d982af), TOBN(0xebb6bf3e, 0xe7544d7c),
+ TOBN(0xd6b9ba76, 0x3d8bd087), TOBN(0x46fe382d, 0x4dc61280)},
+ {TOBN(0xbd39a7e8, 0xb5bdbd75), TOBN(0xab381331, 0xb8f228fe),
+ TOBN(0x0709a77c, 0xce1c4300), TOBN(0x6a247e56, 0xf337ceac)}},
+ {{TOBN(0x8f34f21b, 0x636288be), TOBN(0x9dfdca74, 0xc8a7c305),
+ TOBN(0x6decfd1b, 0xea919e04), TOBN(0xcdf2688d, 0x8e1991f8)},
+ {TOBN(0xe607df44, 0xd0f8a67e), TOBN(0xd985df4b, 0x0b58d010),
+ TOBN(0x57f834c5, 0x0c24f8f4), TOBN(0xe976ef56, 0xa0bf01ae)}},
+ {{TOBN(0x536395ac, 0xa1c32373), TOBN(0x351027aa, 0x734c0a13),
+ TOBN(0xd2f1b5d6, 0x5e6bd5bc), TOBN(0x2b539e24, 0x223debed)},
+ {TOBN(0xd4994cec, 0x0eaa1d71), TOBN(0x2a83381d, 0x661dcf65),
+ TOBN(0x5f1aed2f, 0x7b54c740), TOBN(0x0bea3fa5, 0xd6dda5ee)}},
+ {{TOBN(0x9d4fb684, 0x36cc6134), TOBN(0x8eb9bbf3, 0xc0a443dd),
+ TOBN(0xfc500e2e, 0x383b7d2a), TOBN(0x7aad621c, 0x5b775257)},
+ {TOBN(0x69284d74, 0x0a8f7cc0), TOBN(0xe820c2ce, 0x07562d65),
+ TOBN(0xbf9531b9, 0x499758ee), TOBN(0x73e95ca5, 0x6ee0cc2d)}},
+ {{TOBN(0xf61790ab, 0xfbaf50a5), TOBN(0xdf55e76b, 0x684e0750),
+ TOBN(0xec516da7, 0xf176b005), TOBN(0x575553bb, 0x7a2dddc7)},
+ {TOBN(0x37c87ca3, 0x553afa73), TOBN(0x315f3ffc, 0x4d55c251),
+ TOBN(0xe846442a, 0xaf3e5d35), TOBN(0x61b91149, 0x6495ff28)}},
+ {{TOBN(0x23cc95d3, 0xfa326dc3), TOBN(0x1df4da1f, 0x18fc2cea),
+ TOBN(0x24bf9adc, 0xd0a37d59), TOBN(0xb6710053, 0x320d6e1e)},
+ {TOBN(0x96f9667e, 0x618344d1), TOBN(0xcc7ce042, 0xa06445af),
+ TOBN(0xa02d8514, 0xd68dbc3a), TOBN(0x4ea109e4, 0x280b5a5b)}},
+ {{TOBN(0x5741a7ac, 0xb40961bf), TOBN(0x4ada5937, 0x6aa56bfa),
+ TOBN(0x7feb9145, 0x02b765d1), TOBN(0x561e97be, 0xe6ad1582)},
+ {TOBN(0xbbc4a5b6, 0xda3982f5), TOBN(0x0c2659ed, 0xb546f468),
+ TOBN(0xb8e7e6aa, 0x59612d20), TOBN(0xd83dfe20, 0xac19e8e0)}},
+ {{TOBN(0x8530c45f, 0xb835398c), TOBN(0x6106a8bf, 0xb38a41c2),
+ TOBN(0x21e8f9a6, 0x35f5dcdb), TOBN(0x39707137, 0xcae498ed)},
+ {TOBN(0x70c23834, 0xd8249f00), TOBN(0x9f14b58f, 0xab2537a0),
+ TOBN(0xd043c365, 0x5f61c0c2), TOBN(0xdc5926d6, 0x09a194a7)}},
+ {{TOBN(0xddec0339, 0x8e77738a), TOBN(0xd07a63ef, 0xfba46426),
+ TOBN(0x2e58e79c, 0xee7f6e86), TOBN(0xe59b0459, 0xff32d241)},
+ {TOBN(0xc5ec84e5, 0x20fa0338), TOBN(0x97939ac8, 0xeaff5ace),
+ TOBN(0x0310a4e3, 0xb4a38313), TOBN(0x9115fba2, 0x8f9d9885)}},
+ {{TOBN(0x8dd710c2, 0x5fadf8c3), TOBN(0x66be38a2, 0xce19c0e2),
+ TOBN(0xd42a279c, 0x4cfe5022), TOBN(0x597bb530, 0x0e24e1b8)},
+ {TOBN(0x3cde86b7, 0xc153ca7f), TOBN(0xa8d30fb3, 0x707d63bd),
+ TOBN(0xac905f92, 0xbd60d21e), TOBN(0x98e7ffb6, 0x7b9a54ab)}},
+ {{TOBN(0xd7147df8, 0xe9726a30), TOBN(0xb5e216ff, 0xafce3533),
+ TOBN(0xb550b799, 0x2ff1ec40), TOBN(0x6b613b87, 0xa1e953fd)},
+ {TOBN(0x87b88dba, 0x792d5610), TOBN(0x2ee1270a, 0xa190fbe1),
+ TOBN(0x02f4e2dc, 0x2ef581da), TOBN(0x016530e4, 0xeff82a95)}},
+ {{TOBN(0xcbb93dfd, 0x8fd6ee89), TOBN(0x16d3d986, 0x46848fff),
+ TOBN(0x600eff24, 0x1da47adf), TOBN(0x1b9754a0, 0x0ad47a71)},
+ {TOBN(0x8f9266df, 0x70c33b98), TOBN(0xaadc87ae, 0xdf34186e),
+ TOBN(0x0d2ce8e1, 0x4ad24132), TOBN(0x8a47cbfc, 0x19946eba)}},
+ {{TOBN(0x47feeb66, 0x62b5f3af), TOBN(0xcefab561, 0x0abb3734),
+ TOBN(0x449de60e, 0x19f35cb1), TOBN(0x39f8db14, 0x157f0eb9)},
+ {TOBN(0xffaecc5b, 0x3c61bfd6), TOBN(0xa5a4d41d, 0x41216703),
+ TOBN(0x7f8fabed, 0x224e1cc2), TOBN(0x0d5a8186, 0x871ad953)}},
+ {{TOBN(0xf10774f7, 0xd22da9a9), TOBN(0x45b8a678, 0xcc8a9b0d),
+ TOBN(0xd9c2e722, 0xbdc32cff), TOBN(0xbf71b5f5, 0x337202a5)},
+ {TOBN(0x95c57f2f, 0x69fc4db9), TOBN(0xb6dad34c, 0x765d01e1),
+ TOBN(0x7e0bd13f, 0xcb904635), TOBN(0x61751253, 0x763a588c)}},
+ {{TOBN(0xd85c2997, 0x81af2c2d), TOBN(0xc0f7d9c4, 0x81b9d7da),
+ TOBN(0x838a34ae, 0x08533e8d), TOBN(0x15c4cb08, 0x311d8311)},
+ {TOBN(0x97f83285, 0x8e121e14), TOBN(0xeea7dc1e, 0x85000a5f),
+ TOBN(0x0c6059b6, 0x5d256274), TOBN(0xec9beace, 0xb95075c0)}},
+ {{TOBN(0x173daad7, 0x1df97828), TOBN(0xbf851cb5, 0xa8937877),
+ TOBN(0xb083c594, 0x01646f3c), TOBN(0x3bad30cf, 0x50c6d352)},
+ {TOBN(0xfeb2b202, 0x496bbcea), TOBN(0x3cf9fd4f, 0x18a1e8ba),
+ TOBN(0xd26de7ff, 0x1c066029), TOBN(0x39c81e9e, 0x4e9ed4f8)}},
+ {{TOBN(0xd8be0cb9, 0x7b390d35), TOBN(0x01df2bbd, 0x964aab27),
+ TOBN(0x3e8c1a65, 0xc3ef64f8), TOBN(0x567291d1, 0x716ed1dd)},
+ {TOBN(0x95499c6c, 0x5f5406d3), TOBN(0x71fdda39, 0x5ba8e23f),
+ TOBN(0xcfeb320e, 0xd5096ece), TOBN(0xbe7ba92b, 0xca66dd16)}},
+ {{TOBN(0x4608d36b, 0xc6fb5a7d), TOBN(0xe3eea15a, 0x6d2dd0e0),
+ TOBN(0x75b0a3eb, 0x8f97a36a), TOBN(0xf59814cc, 0x1c83de1e)},
+ {TOBN(0x56c9c5b0, 0x1c33c23f), TOBN(0xa96c1da4, 0x6faa4136),
+ TOBN(0x46bf2074, 0xde316551), TOBN(0x3b866e7b, 0x1f756c8f)}},
+ {{TOBN(0x727727d8, 0x1495ed6b), TOBN(0xb2394243, 0xb682dce7),
+ TOBN(0x8ab8454e, 0x758610f3), TOBN(0xc243ce84, 0x857d72a4)},
+ {TOBN(0x7b320d71, 0xdbbf370f), TOBN(0xff9afa37, 0x78e0f7ca),
+ TOBN(0x0119d1e0, 0xea7b523f), TOBN(0xb997f8cb, 0x058c7d42)}},
+ {{TOBN(0x285bcd2a, 0x37bbb184), TOBN(0x51dcec49, 0xa45d1fa6),
+ TOBN(0x6ade3b64, 0xe29634cb), TOBN(0x080c94a7, 0x26b86ef1)},
+ {TOBN(0xba583db1, 0x2283fbe3), TOBN(0x902bddc8, 0x5a9315ed),
+ TOBN(0x07c1ccb3, 0x86964bec), TOBN(0x78f4eacf, 0xb6258301)}},
+ {{TOBN(0x4bdf3a49, 0x56f90823), TOBN(0xba0f5080, 0x741d777b),
+ TOBN(0x091d71c3, 0xf38bf760), TOBN(0x9633d50f, 0x9b625b02)},
+ {TOBN(0x03ecb743, 0xb8c9de61), TOBN(0xb4751254, 0x5de74720),
+ TOBN(0x9f9defc9, 0x74ce1cb2), TOBN(0x774a4f6a, 0x00bd32ef)}},
+ {{TOBN(0xaca385f7, 0x73848f22), TOBN(0x53dad716, 0xf3f8558e),
+ TOBN(0xab7b34b0, 0x93c471f9), TOBN(0xf530e069, 0x19644bc7)},
+ {TOBN(0x3d9fb1ff, 0xdd59d31a), TOBN(0x4382e0df, 0x08daa795),
+ TOBN(0x165c6f4b, 0xd5cc88d7), TOBN(0xeaa392d5, 0x4a18c900)}},
+ {{TOBN(0x94203c67, 0x648024ee), TOBN(0x188763f2, 0x8c2fabcd),
+ TOBN(0xa80f87ac, 0xbbaec835), TOBN(0x632c96e0, 0xf29d8d54)},
+ {TOBN(0x29b0a60e, 0x4c00a95e), TOBN(0x2ef17f40, 0xe011e9fa),
+ TOBN(0xf6c0e1d1, 0x15b77223), TOBN(0xaaec2c62, 0x14b04e32)}},
+ {{TOBN(0xd35688d8, 0x3d84e58c), TOBN(0x2af5094c, 0x958571db),
+ TOBN(0x4fff7e19, 0x760682a6), TOBN(0x4cb27077, 0xe39a407c)},
+ {TOBN(0x0f59c547, 0x4ff0e321), TOBN(0x169f34a6, 0x1b34c8ff),
+ TOBN(0x2bff1096, 0x52bc1ba7), TOBN(0xa25423b7, 0x83583544)}},
+ {{TOBN(0x5d55d5d5, 0x0ac8b782), TOBN(0xff6622ec, 0x2db3c892),
+ TOBN(0x48fce741, 0x6b8bb642), TOBN(0x31d6998c, 0x69d7e3dc)},
+ {TOBN(0xdbaf8004, 0xcadcaed0), TOBN(0x801b0142, 0xd81d053c),
+ TOBN(0x94b189fc, 0x59630ec6), TOBN(0x120e9934, 0xaf762c8e)}},
+ {{TOBN(0x53a29aa4, 0xfdc6a404), TOBN(0x19d8e01e, 0xa1909948),
+ TOBN(0x3cfcabf1, 0xd7e89681), TOBN(0x3321a50d, 0x4e132d37)},
+ {TOBN(0xd0496863, 0xe9a86111), TOBN(0x8c0cde61, 0x06a3bc65),
+ TOBN(0xaf866c49, 0xfc9f8eef), TOBN(0x2066350e, 0xff7f5141)}},
+ {{TOBN(0x4f8a4689, 0xe56ddfbd), TOBN(0xea1b0c07, 0xfe32983a),
+ TOBN(0x2b317462, 0x873cb8cb), TOBN(0x658deddc, 0x2d93229f)},
+ {TOBN(0x65efaf4d, 0x0f64ef58), TOBN(0xfe43287d, 0x730cc7a8),
+ TOBN(0xaebc0c72, 0x3d047d70), TOBN(0x92efa539, 0xd92d26c9)}},
+ {{TOBN(0x06e78457, 0x94b56526), TOBN(0x415cb80f, 0x0961002d),
+ TOBN(0x89e5c565, 0x76dcb10f), TOBN(0x8bbb6982, 0xff9259fe)},
+ {TOBN(0x4fe8795b, 0x9abc2668), TOBN(0xb5d4f534, 0x1e678fb1),
+ TOBN(0x6601f3be, 0x7b7da2b9), TOBN(0x98da59e2, 0xa13d6805)}},
+ {{TOBN(0x190d8ea6, 0x01799a52), TOBN(0xa20cec41, 0xb86d2952),
+ TOBN(0x3062ffb2, 0x7fff2a7c), TOBN(0x741b32e5, 0x79f19d37)},
+ {TOBN(0xf80d8181, 0x4eb57d47), TOBN(0x7a2d0ed4, 0x16aef06b),
+ TOBN(0x09735fb0, 0x1cecb588), TOBN(0x1641caaa, 0xc6061f5b)}}},
+ {{{TOBN(0x7f99824f, 0x20151427), TOBN(0x206828b6, 0x92430206),
+ TOBN(0xaa9097d7, 0xe1112357), TOBN(0xacf9a2f2, 0x09e414ec)},
+ {TOBN(0xdbdac9da, 0x27915356), TOBN(0x7e0734b7, 0x001efee3),
+ TOBN(0x54fab5bb, 0xd2b288e2), TOBN(0x4c630fc4, 0xf62dd09c)}},
+ {{TOBN(0x8537107a, 0x1ac2703b), TOBN(0xb49258d8, 0x6bc857b5),
+ TOBN(0x57df14de, 0xbcdaccd1), TOBN(0x24ab68d7, 0xc4ae8529)},
+ {TOBN(0x7ed8b5d4, 0x734e59d0), TOBN(0x5f8740c8, 0xc495cc80),
+ TOBN(0x84aedd5a, 0x291db9b3), TOBN(0x80b360f8, 0x4fb995be)}},
+ {{TOBN(0xae915f5d, 0x5fa067d1), TOBN(0x4134b57f, 0x9668960c),
+ TOBN(0xbd3656d6, 0xa48edaac), TOBN(0xdac1e3e4, 0xfc1d7436)},
+ {TOBN(0x674ff869, 0xd81fbb26), TOBN(0x449ed3ec, 0xb26c33d4),
+ TOBN(0x85138705, 0xd94203e8), TOBN(0xccde538b, 0xbeeb6f4a)}},
+ {{TOBN(0x55d5c68d, 0xa61a76fa), TOBN(0x598b441d, 0xca1554dc),
+ TOBN(0xd39923b9, 0x773b279c), TOBN(0x33331d3c, 0x36bf9efc)},
+ {TOBN(0x2d4c848e, 0x298de399), TOBN(0xcfdb8e77, 0xa1a27f56),
+ TOBN(0x94c855ea, 0x57b8ab70), TOBN(0xdcdb9dae, 0x6f7879ba)}},
+ {{TOBN(0x7bdff8c2, 0x019f2a59), TOBN(0xb3ce5bb3, 0xcb4fbc74),
+ TOBN(0xea907f68, 0x8a9173dd), TOBN(0x6cd3d0d3, 0x95a75439)},
+ {TOBN(0x92ecc4d6, 0xefed021c), TOBN(0x09a9f9b0, 0x6a77339a),
+ TOBN(0x87ca6b15, 0x7188c64a), TOBN(0x10c29968, 0x44899158)}},
+ {{TOBN(0x5859a229, 0xed6e82ef), TOBN(0x16f338e3, 0x65ebaf4e),
+ TOBN(0x0cd31387, 0x5ead67ae), TOBN(0x1c73d228, 0x54ef0bb4)},
+ {TOBN(0x4cb55131, 0x74a5c8c7), TOBN(0x01cd2970, 0x7f69ad6a),
+ TOBN(0xa04d00dd, 0xe966f87e), TOBN(0xd96fe447, 0x0b7b0321)}},
+ {{TOBN(0x342ac06e, 0x88fbd381), TOBN(0x02cd4a84, 0x5c35a493),
+ TOBN(0xe8fa89de, 0x54f1bbcd), TOBN(0x341d6367, 0x2575ed4c)},
+ {TOBN(0xebe357fb, 0xd238202b), TOBN(0x600b4d1a, 0xa984ead9),
+ TOBN(0xc35c9f44, 0x52436ea0), TOBN(0x96fe0a39, 0xa370751b)}},
+ {{TOBN(0x4c4f0736, 0x7f636a38), TOBN(0x9f943fb7, 0x0e76d5cb),
+ TOBN(0xb03510ba, 0xa8b68b8b), TOBN(0xc246780a, 0x9ed07a1f)},
+ {TOBN(0x3c051415, 0x6d549fc2), TOBN(0xc2953f31, 0x607781ca),
+ TOBN(0x955e2c69, 0xd8d95413), TOBN(0xb300fadc, 0x7bd282e3)}},
+ {{TOBN(0x81fe7b50, 0x87e9189f), TOBN(0xdb17375c, 0xf42dda27),
+ TOBN(0x22f7d896, 0xcf0a5904), TOBN(0xa0e57c5a, 0xebe348e6)},
+ {TOBN(0xa61011d3, 0xf40e3c80), TOBN(0xb1189321, 0x8db705c5),
+ TOBN(0x4ed9309e, 0x50fedec3), TOBN(0xdcf14a10, 0x4d6d5c1d)}},
+ {{TOBN(0x056c265b, 0x55691342), TOBN(0xe8e08504, 0x91049dc7),
+ TOBN(0x131329f5, 0xc9bae20a), TOBN(0x96c8b3e8, 0xd9dccdb4)},
+ {TOBN(0x8c5ff838, 0xfb4ee6b4), TOBN(0xfc5a9aeb, 0x41e8ccf0),
+ TOBN(0x7417b764, 0xfae050c6), TOBN(0x0953c3d7, 0x00452080)}},
+ {{TOBN(0x21372682, 0x38dfe7e8), TOBN(0xea417e15, 0x2bb79d4b),
+ TOBN(0x59641f1c, 0x76e7cf2d), TOBN(0x271e3059, 0xea0bcfcc)},
+ {TOBN(0x624c7dfd, 0x7253ecbd), TOBN(0x2f552e25, 0x4fca6186),
+ TOBN(0xcbf84ecd, 0x4d866e9c), TOBN(0x73967709, 0xf68d4610)}},
+ {{TOBN(0xa14b1163, 0xc27901b4), TOBN(0xfd9236e0, 0x899b8bf3),
+ TOBN(0x42b091ec, 0xcbc6da0a), TOBN(0xbb1dac6f, 0x5ad1d297)},
+ {TOBN(0x80e61d53, 0xa91cf76e), TOBN(0x4110a412, 0xd31f1ee7),
+ TOBN(0x2d87c3ba, 0x13efcf77), TOBN(0x1f374bb4, 0xdf450d76)}},
+ {{TOBN(0x5e78e2f2, 0x0d188dab), TOBN(0xe3968ed0, 0xf4b885ef),
+ TOBN(0x46c0568e, 0x7314570f), TOBN(0x31616338, 0x01170521)},
+ {TOBN(0x18e1e7e2, 0x4f0c8afe), TOBN(0x4caa75ff, 0xdeea78da),
+ TOBN(0x82db67f2, 0x7c5d8a51), TOBN(0x36a44d86, 0x6f505370)}},
+ {{TOBN(0xd72c5bda, 0x0333974f), TOBN(0x5db516ae, 0x27a70146),
+ TOBN(0x34705281, 0x210ef921), TOBN(0xbff17a8f, 0x0c9c38e5)},
+ {TOBN(0x78f4814e, 0x12476da1), TOBN(0xc1e16613, 0x33c16980),
+ TOBN(0x9e5b386f, 0x424d4bca), TOBN(0x4c274e87, 0xc85740de)}},
+ {{TOBN(0xb6a9b88d, 0x6c2f5226), TOBN(0x14d1b944, 0x550d7ca8),
+ TOBN(0x580c85fc, 0x1fc41709), TOBN(0xc1da368b, 0x54c6d519)},
+ {TOBN(0x2b0785ce, 0xd5113cf7), TOBN(0x0670f633, 0x5a34708f),
+ TOBN(0x46e23767, 0x15cc3f88), TOBN(0x1b480cfa, 0x50c72c8f)}},
+ {{TOBN(0x20288602, 0x4147519a), TOBN(0xd0981eac, 0x26b372f0),
+ TOBN(0xa9d4a7ca, 0xa785ebc8), TOBN(0xd953c50d, 0xdbdf58e9)},
+ {TOBN(0x9d6361cc, 0xfd590f8f), TOBN(0x72e9626b, 0x44e6c917),
+ TOBN(0x7fd96110, 0x22eb64cf), TOBN(0x863ebb7e, 0x9eb288f3)}},
+ {{TOBN(0x6e6ab761, 0x6aca8ee7), TOBN(0x97d10b39, 0xd7b40358),
+ TOBN(0x1687d377, 0x1e5feb0d), TOBN(0xc83e50e4, 0x8265a27a)},
+ {TOBN(0x8f75a9fe, 0xc954b313), TOBN(0xcc2e8f47, 0x310d1f61),
+ TOBN(0xf5ba81c5, 0x6557d0e0), TOBN(0x25f9680c, 0x3eaf6207)}},
+ {{TOBN(0xf95c6609, 0x4354080b), TOBN(0x5225bfa5, 0x7bf2fe1c),
+ TOBN(0xc5c004e2, 0x5c7d98fa), TOBN(0x3561bf1c, 0x019aaf60)},
+ {TOBN(0x5e6f9f17, 0xba151474), TOBN(0xdec2f934, 0xb04f6eca),
+ TOBN(0x64e368a1, 0x269acb1e), TOBN(0x1332d9e4, 0x0cdda493)}},
+ {{TOBN(0x60d6cf69, 0xdf23de05), TOBN(0x66d17da2, 0x009339a0),
+ TOBN(0x9fcac985, 0x0a693923), TOBN(0xbcf057fc, 0xed7c6a6d)},
+ {TOBN(0xc3c5c8c5, 0xf0b5662c), TOBN(0x25318dd8, 0xdcba4f24),
+ TOBN(0x60e8cb75, 0x082b69ff), TOBN(0x7c23b3ee, 0x1e728c01)}},
+ {{TOBN(0x15e10a0a, 0x097e4403), TOBN(0xcb3d0a86, 0x19854665),
+ TOBN(0x88d8e211, 0xd67d4826), TOBN(0xb39af66e, 0x0b9d2839)},
+ {TOBN(0xa5f94588, 0xbd475ca8), TOBN(0xe06b7966, 0xc077b80b),
+ TOBN(0xfedb1485, 0xda27c26c), TOBN(0xd290d33a, 0xfe0fd5e0)}},
+ {{TOBN(0xa40bcc47, 0xf34fb0fa), TOBN(0xb4760cc8, 0x1fb1ab09),
+ TOBN(0x8fca0993, 0xa273bfe3), TOBN(0x13e4fe07, 0xf70b213c)},
+ {TOBN(0x3bcdb992, 0xfdb05163), TOBN(0x8c484b11, 0x0c2b19b6),
+ TOBN(0x1acb815f, 0xaaf2e3e2), TOBN(0xc6905935, 0xb89ff1b4)}},
+ {{TOBN(0xb2ad6f9d, 0x586e74e1), TOBN(0x488883ad, 0x67b80484),
+ TOBN(0x758aa2c7, 0x369c3ddb), TOBN(0x8ab74e69, 0x9f9afd31)},
+ {TOBN(0x10fc2d28, 0x5e21beb1), TOBN(0x3484518a, 0x318c42f9),
+ TOBN(0x377427dc, 0x53cf40c3), TOBN(0x9de0781a, 0x391bc1d9)}},
+ {{TOBN(0x8faee858, 0x693807e1), TOBN(0xa3865327, 0x4e81ccc7),
+ TOBN(0x02c30ff2, 0x6f835b84), TOBN(0xb604437b, 0x0d3d38d4)},
+ {TOBN(0xb3fc8a98, 0x5ca1823d), TOBN(0xb82f7ec9, 0x03be0324),
+ TOBN(0xee36d761, 0xcf684a33), TOBN(0x5a01df0e, 0x9f29bf7d)}},
+ {{TOBN(0x686202f3, 0x1306583d), TOBN(0x05b10da0, 0x437c622e),
+ TOBN(0xbf9aaa0f, 0x076a7bc8), TOBN(0x25e94efb, 0x8f8f4e43)},
+ {TOBN(0x8a35c9b7, 0xfa3dc26d), TOBN(0xe0e5fb93, 0x96ff03c5),
+ TOBN(0xa77e3843, 0xebc394ce), TOBN(0xcede6595, 0x8361de60)}},
+ {{TOBN(0xd27c22f6, 0xa1993545), TOBN(0xab01cc36, 0x24d671ba),
+ TOBN(0x63fa2877, 0xa169c28e), TOBN(0x925ef904, 0x2eb08376)},
+ {TOBN(0x3b2fa3cf, 0x53aa0b32), TOBN(0xb27beb5b, 0x71c49d7a),
+ TOBN(0xb60e1834, 0xd105e27f), TOBN(0xd6089788, 0x4f68570d)}},
+ {{TOBN(0x23094ce0, 0xd6fbc2ac), TOBN(0x738037a1, 0x815ff551),
+ TOBN(0xda73b1bb, 0x6bef119c), TOBN(0xdcf6c430, 0xeef506ba)},
+ {TOBN(0x00e4fe7b, 0xe3ef104a), TOBN(0xebdd9a2c, 0x0a065628),
+ TOBN(0x853a81c3, 0x8792043e), TOBN(0x22ad6ece, 0xb3b59108)}},
+ {{TOBN(0x9fb813c0, 0x39cd297d), TOBN(0x8ec7e16e, 0x05bda5d9),
+ TOBN(0x2834797c, 0x0d104b96), TOBN(0xcc11a2e7, 0x7c511510)},
+ {TOBN(0x96ca5a53, 0x96ee6380), TOBN(0x054c8655, 0xcea38742),
+ TOBN(0xb5946852, 0xd54dfa7d), TOBN(0x97c422e7, 0x1f4ab207)}},
+ {{TOBN(0xbf907509, 0x0c22b540), TOBN(0x2cde42aa, 0xb7c267d4),
+ TOBN(0xba18f9ed, 0x5ab0d693), TOBN(0x3ba62aa6, 0x6e4660d9)},
+ {TOBN(0xb24bf97b, 0xab9ea96a), TOBN(0x5d039642, 0xe3b60e32),
+ TOBN(0x4e6a4506, 0x7c4d9bd5), TOBN(0x666c5b9e, 0x7ed4a6a4)}},
+ {{TOBN(0xfa3fdcd9, 0x8edbd7cc), TOBN(0x4660bb87, 0xc6ccd753),
+ TOBN(0x9ae90820, 0x21e6b64f), TOBN(0x8a56a713, 0xb36bfb3f)},
+ {TOBN(0xabfce096, 0x5726d47f), TOBN(0x9eed01b2, 0x0b1a9a7f),
+ TOBN(0x30e9cad4, 0x4eb74a37), TOBN(0x7b2524cc, 0x53e9666d)}},
+ {{TOBN(0x6a29683b, 0x8f4b002f), TOBN(0xc2200d7a, 0x41f4fc20),
+ TOBN(0xcf3af47a, 0x3a338acc), TOBN(0x6539a4fb, 0xe7128975)},
+ {TOBN(0xcec31c14, 0xc33c7fcf), TOBN(0x7eb6799b, 0xc7be322b),
+ TOBN(0x119ef4e9, 0x6646f623), TOBN(0x7b7a26a5, 0x54d7299b)}},
+ {{TOBN(0xcb37f08d, 0x403f46f2), TOBN(0x94b8fc43, 0x1a0ec0c7),
+ TOBN(0xbb8514e3, 0xc332142f), TOBN(0xf3ed2c33, 0xe80d2a7a)},
+ {TOBN(0x8d2080af, 0xb639126c), TOBN(0xf7b6be60, 0xe3553ade),
+ TOBN(0x3950aa9f, 0x1c7e2b09), TOBN(0x847ff958, 0x6410f02b)}},
+ {{TOBN(0x877b7cf5, 0x678a31b0), TOBN(0xd50301ae, 0x3998b620),
+ TOBN(0x734257c5, 0xc00fb396), TOBN(0xf9fb18a0, 0x04e672a6)},
+ {TOBN(0xff8bd8eb, 0xe8758851), TOBN(0x1e64e4c6, 0x5d99ba44),
+ TOBN(0x4b8eaedf, 0x7dfd93b7), TOBN(0xba2f2a98, 0x04e76b8c)}},
+ {{TOBN(0x7d790cba, 0xe8053433), TOBN(0xc8e725a0, 0x3d2c9585),
+ TOBN(0x58c5c476, 0xcdd8f5ed), TOBN(0xd106b952, 0xefa9fe1d)},
+ {TOBN(0x3c5c775b, 0x0eff13a9), TOBN(0x242442ba, 0xe057b930),
+ TOBN(0xe9f458d4, 0xc9b70cbd), TOBN(0x69b71448, 0xa3cdb89a)}},
+ {{TOBN(0x41ee46f6, 0x0e2ed742), TOBN(0x573f1045, 0x40067493),
+ TOBN(0xb1e154ff, 0x9d54c304), TOBN(0x2ad0436a, 0x8d3a7502)},
+ {TOBN(0xee4aaa2d, 0x431a8121), TOBN(0xcd38b3ab, 0x886f11ed),
+ TOBN(0x57d49ea6, 0x034a0eb7), TOBN(0xd2b773bd, 0xf7e85e58)}},
+ {{TOBN(0x4a559ac4, 0x9b5c1f14), TOBN(0xc444be1a, 0x3e54df2b),
+ TOBN(0x13aad704, 0xeda41891), TOBN(0xcd927bec, 0x5eb5c788)},
+ {TOBN(0xeb3c8516, 0xe48c8a34), TOBN(0x1b7ac812, 0x4b546669),
+ TOBN(0x1815f896, 0x594df8ec), TOBN(0x87c6a79c, 0x79227865)}},
+ {{TOBN(0xae02a2f0, 0x9b56ddbd), TOBN(0x1339b5ac, 0x8a2f1cf3),
+ TOBN(0xf2b569c7, 0x839dff0d), TOBN(0xb0b9e864, 0xfee9a43d)},
+ {TOBN(0x4ff8ca41, 0x77bb064e), TOBN(0x145a2812, 0xfd249f63),
+ TOBN(0x3ab7beac, 0xf86f689a), TOBN(0x9bafec27, 0x01d35f5e)}},
+ {{TOBN(0x28054c65, 0x4265aa91), TOBN(0xa4b18304, 0x035efe42),
+ TOBN(0x6887b0e6, 0x9639dec7), TOBN(0xf4b8f6ad, 0x3d52aea5)},
+ {TOBN(0xfb9293cc, 0x971a8a13), TOBN(0x3f159e5d, 0x4c934d07),
+ TOBN(0x2c50e9b1, 0x09acbc29), TOBN(0x08eb65e6, 0x7154d129)}},
+ {{TOBN(0x4feff589, 0x30b75c3e), TOBN(0x0bb82fe2, 0x94491c93),
+ TOBN(0xd8ac377a, 0x89af62bb), TOBN(0xd7b51490, 0x9685e49f)},
+ {TOBN(0xabca9a7b, 0x04497f19), TOBN(0x1b35ed0a, 0x1a7ad13f),
+ TOBN(0x6b601e21, 0x3ec86ed6), TOBN(0xda91fcb9, 0xce0c76f1)}},
+ {{TOBN(0x9e28507b, 0xd7ab27e1), TOBN(0x7c19a555, 0x63945b7b),
+ TOBN(0x6b43f0a1, 0xaafc9827), TOBN(0x443b4fbd, 0x3aa55b91)},
+ {TOBN(0x962b2e65, 0x6962c88f), TOBN(0x139da8d4, 0xce0db0ca),
+ TOBN(0xb93f05dd, 0x1b8d6c4f), TOBN(0x779cdff7, 0x180b9824)}},
+ {{TOBN(0xbba23fdd, 0xae57c7b7), TOBN(0x345342f2, 0x1b932522),
+ TOBN(0xfd9c80fe, 0x556d4aa3), TOBN(0xa03907ba, 0x6525bb61)},
+ {TOBN(0x38b010e1, 0xff218933), TOBN(0xc066b654, 0xaa52117b),
+ TOBN(0x8e141920, 0x94f2e6ea), TOBN(0x66a27dca, 0x0d32f2b2)}},
+ {{TOBN(0x69c7f993, 0x048b3717), TOBN(0xbf5a989a, 0xb178ae1c),
+ TOBN(0x49fa9058, 0x564f1d6b), TOBN(0x27ec6e15, 0xd31fde4e)},
+ {TOBN(0x4cce0373, 0x7276e7fc), TOBN(0x64086d79, 0x89d6bf02),
+ TOBN(0x5a72f046, 0x4ccdd979), TOBN(0x909c3566, 0x47775631)}},
+ {{TOBN(0x1c07bc6b, 0x75dd7125), TOBN(0xb4c6bc97, 0x87a0428d),
+ TOBN(0x507ece52, 0xfdeb6b9d), TOBN(0xfca56512, 0xb2c95432)},
+ {TOBN(0x15d97181, 0xd0e8bd06), TOBN(0x384dd317, 0xc6bb46ea),
+ TOBN(0x5441ea20, 0x3952b624), TOBN(0xbcf70dee, 0x4e7dc2fb)}},
+ {{TOBN(0x372b016e, 0x6628e8c3), TOBN(0x07a0d667, 0xb60a7522),
+ TOBN(0xcf05751b, 0x0a344ee2), TOBN(0x0ec09a48, 0x118bdeec)},
+ {TOBN(0x6e4b3d4e, 0xd83dce46), TOBN(0x43a6316d, 0x99d2fc6e),
+ TOBN(0xa99d8989, 0x56cf044c), TOBN(0x7c7f4454, 0xae3e5fb7)}},
+ {{TOBN(0xb2e6b121, 0xfbabbe92), TOBN(0x281850fb, 0xe1330076),
+ TOBN(0x093581ec, 0x97890015), TOBN(0x69b1dded, 0x75ff77f5)},
+ {TOBN(0x7cf0b18f, 0xab105105), TOBN(0x953ced31, 0xa89ccfef),
+ TOBN(0x3151f85f, 0xeb914009), TOBN(0x3c9f1b87, 0x88ed48ad)}},
+ {{TOBN(0xc9aba1a1, 0x4a7eadcb), TOBN(0x928e7501, 0x522e71cf),
+ TOBN(0xeaede727, 0x3a2e4f83), TOBN(0x467e10d1, 0x1ce3bbd3)},
+ {TOBN(0xf3442ac3, 0xb955dcf0), TOBN(0xba96307d, 0xd3d5e527),
+ TOBN(0xf763a10e, 0xfd77f474), TOBN(0x5d744bd0, 0x6a6e1ff0)}},
+ {{TOBN(0xd287282a, 0xa777899e), TOBN(0xe20eda8f, 0xd03f3cde),
+ TOBN(0x6a7e75bb, 0x50b07d31), TOBN(0x0b7e2a94, 0x6f379de4)},
+ {TOBN(0x31cb64ad, 0x19f593cf), TOBN(0x7b1a9e4f, 0x1e76ef1d),
+ TOBN(0xe18c9c9d, 0xb62d609c), TOBN(0x439bad6d, 0xe779a650)}},
+ {{TOBN(0x219d9066, 0xe032f144), TOBN(0x1db632b8, 0xe8b2ec6a),
+ TOBN(0xff0d0fd4, 0xfda12f78), TOBN(0x56fb4c2d, 0x2a25d265)},
+ {TOBN(0x5f4e2ee1, 0x255a03f1), TOBN(0x61cd6af2, 0xe96af176),
+ TOBN(0xe0317ba8, 0xd068bc97), TOBN(0x927d6bab, 0x264b988e)}},
+ {{TOBN(0xa18f07e0, 0xe90fb21e), TOBN(0x00fd2b80, 0xbba7fca1),
+ TOBN(0x20387f27, 0x95cd67b5), TOBN(0x5b89a4e7, 0xd39707f7)},
+ {TOBN(0x8f83ad3f, 0x894407ce), TOBN(0xa0025b94, 0x6c226132),
+ TOBN(0xc79563c7, 0xf906c13b), TOBN(0x5f548f31, 0x4e7bb025)}},
+ {{TOBN(0x2b4c6b8f, 0xeac6d113), TOBN(0xa67e3f9c, 0x0e813c76),
+ TOBN(0x3982717c, 0x3fe1f4b9), TOBN(0x58865819, 0x26d8050e)},
+ {TOBN(0x99f3640c, 0xf7f06f20), TOBN(0xdc610216, 0x2a66ebc2),
+ TOBN(0x52f2c175, 0x767a1e08), TOBN(0x05660e1a, 0x5999871b)}},
+ {{TOBN(0x6b0f1762, 0x6d3c4693), TOBN(0xf0e7d627, 0x37ed7bea),
+ TOBN(0xc51758c7, 0xb75b226d), TOBN(0x40a88628, 0x1f91613b)},
+ {TOBN(0x889dbaa7, 0xbbb38ce0), TOBN(0xe0404b65, 0xbddcad81),
+ TOBN(0xfebccd3a, 0x8bc9671f), TOBN(0xfbf9a357, 0xee1f5375)}},
+ {{TOBN(0x5dc169b0, 0x28f33398), TOBN(0xb07ec11d, 0x72e90f65),
+ TOBN(0xae7f3b4a, 0xfaab1eb1), TOBN(0xd970195e, 0x5f17538a)},
+ {TOBN(0x52b05cbe, 0x0181e640), TOBN(0xf5debd62, 0x2643313d),
+ TOBN(0x76148154, 0x5df31f82), TOBN(0x23e03b33, 0x3a9e13c5)}},
+ {{TOBN(0xff758949, 0x4fde0c1f), TOBN(0xbf8a1abe, 0xe5b6ec20),
+ TOBN(0x702278fb, 0x87e1db6c), TOBN(0xc447ad7a, 0x35ed658f)},
+ {TOBN(0x48d4aa38, 0x03d0ccf2), TOBN(0x80acb338, 0x819a7c03),
+ TOBN(0x9bc7c89e, 0x6e17cecc), TOBN(0x46736b8b, 0x03be1d82)}},
+ {{TOBN(0xd65d7b60, 0xc0432f96), TOBN(0xddebe7a3, 0xdeb5442f),
+ TOBN(0x79a25307, 0x7dff69a2), TOBN(0x37a56d94, 0x02cf3122)},
+ {TOBN(0x8bab8aed, 0xf2350d0a), TOBN(0x13c3f276, 0x037b0d9a),
+ TOBN(0xc664957c, 0x44c65cae), TOBN(0x88b44089, 0xc2e71a88)}},
+ {{TOBN(0xdb88e5a3, 0x5cb02664), TOBN(0x5d4c0bf1, 0x8686c72e),
+ TOBN(0xea3d9b62, 0xa682d53e), TOBN(0x9b605ef4, 0x0b2ad431)},
+ {TOBN(0x71bac202, 0xc69645d0), TOBN(0xa115f03a, 0x6a1b66e7),
+ TOBN(0xfe2c563a, 0x158f4dc4), TOBN(0xf715b3a0, 0x4d12a78c)}},
+ {{TOBN(0x8f7f0a48, 0xd413213a), TOBN(0x2035806d, 0xc04becdb),
+ TOBN(0xecd34a99, 0x5d8587f5), TOBN(0x4d8c3079, 0x9f6d3a71)},
+ {TOBN(0x1b2a2a67, 0x8d95a8f6), TOBN(0xc58c9d7d, 0xf2110d0d),
+ TOBN(0xdeee81d5, 0xcf8fba3f), TOBN(0xa42be3c0, 0x0c7cdf68)}},
+ {{TOBN(0x2126f742, 0xd43b5eaa), TOBN(0x054a0766, 0xdfa59b85),
+ TOBN(0x9d0d5e36, 0x126bfd45), TOBN(0xa1f8fbd7, 0x384f8a8f)},
+ {TOBN(0x317680f5, 0xd563fccc), TOBN(0x48ca5055, 0xf280a928),
+ TOBN(0xe00b81b2, 0x27b578cf), TOBN(0x10aad918, 0x2994a514)}},
+ {{TOBN(0xd9e07b62, 0xb7bdc953), TOBN(0x9f0f6ff2, 0x5bc086dd),
+ TOBN(0x09d1ccff, 0x655eee77), TOBN(0x45475f79, 0x5bef7df1)},
+ {TOBN(0x3faa28fa, 0x86f702cc), TOBN(0x92e60905, 0x0f021f07),
+ TOBN(0xe9e62968, 0x7f8fa8c6), TOBN(0xbd71419a, 0xf036ea2c)}},
+ {{TOBN(0x171ee1cc, 0x6028da9a), TOBN(0x5352fe1a, 0xc251f573),
+ TOBN(0xf8ff236e, 0x3fa997f4), TOBN(0xd831b6c9, 0xa5749d5f)},
+ {TOBN(0x7c872e1d, 0xe350e2c2), TOBN(0xc56240d9, 0x1e0ce403),
+ TOBN(0xf9deb077, 0x6974f5cb), TOBN(0x7d50ba87, 0x961c3728)}},
+ {{TOBN(0xd6f89426, 0x5a3a2518), TOBN(0xcf817799, 0xc6303d43),
+ TOBN(0x510a0471, 0x619e5696), TOBN(0xab049ff6, 0x3a5e307b)},
+ {TOBN(0xe4cdf9b0, 0xfeb13ec7), TOBN(0xd5e97117, 0x9d8ff90c),
+ TOBN(0xf6f64d06, 0x9afa96af), TOBN(0x00d0bf5e, 0x9d2012a2)}},
+ {{TOBN(0xe63f301f, 0x358bcdc0), TOBN(0x07689e99, 0x0a9d47f8),
+ TOBN(0x1f689e2f, 0x4f43d43a), TOBN(0x4d542a16, 0x90920904)},
+ {TOBN(0xaea293d5, 0x9ca0a707), TOBN(0xd061fe45, 0x8ac68065),
+ TOBN(0x1033bf1b, 0x0090008c), TOBN(0x29749558, 0xc08a6db6)}},
+ {{TOBN(0x74b5fc59, 0xc1d5d034), TOBN(0xf712e9f6, 0x67e215e0),
+ TOBN(0xfd520cbd, 0x860200e6), TOBN(0x0229acb4, 0x3ea22588)},
+ {TOBN(0x9cd1e14c, 0xfff0c82e), TOBN(0x87684b62, 0x59c69e73),
+ TOBN(0xda85e61c, 0x96ccb989), TOBN(0x2d5dbb02, 0xa3d06493)}},
+ {{TOBN(0xf22ad33a, 0xe86b173c), TOBN(0xe8e41ea5, 0xa79ff0e3),
+ TOBN(0x01d2d725, 0xdd0d0c10), TOBN(0x31f39088, 0x032d28f9)},
+ {TOBN(0x7b3f71e1, 0x7829839e), TOBN(0x0cf691b4, 0x4502ae58),
+ TOBN(0xef658dbd, 0xbefc6115), TOBN(0xa5cd6ee5, 0xb3ab5314)}},
+ {{TOBN(0x206c8d7b, 0x5f1d2347), TOBN(0x794645ba, 0x4cc2253a),
+ TOBN(0xd517d8ff, 0x58389e08), TOBN(0x4fa20dee, 0x9f847288)},
+ {TOBN(0xeba072d8, 0xd797770a), TOBN(0x7360c91d, 0xbf429e26),
+ TOBN(0x7200a3b3, 0x80af8279), TOBN(0x6a1c9150, 0x82dadce3)}},
+ {{TOBN(0x0ee6d3a7, 0xc35d8794), TOBN(0x042e6558, 0x0356bae5),
+ TOBN(0x9f59698d, 0x643322fd), TOBN(0x9379ae15, 0x50a61967)},
+ {TOBN(0x64b9ae62, 0xfcc9981e), TOBN(0xaed3d631, 0x6d2934c6),
+ TOBN(0x2454b302, 0x5e4e65eb), TOBN(0xab09f647, 0xf9950428)}}},
+ {{{TOBN(0xb2083a12, 0x22248acc), TOBN(0x1f6ec0ef, 0x3264e366),
+ TOBN(0x5659b704, 0x5afdee28), TOBN(0x7a823a40, 0xe6430bb5)},
+ {TOBN(0x24592a04, 0xe1900a79), TOBN(0xcde09d4a, 0xc9ee6576),
+ TOBN(0x52b6463f, 0x4b5ea54a), TOBN(0x1efe9ed3, 0xd3ca65a7)}},
+ {{TOBN(0xe27a6dbe, 0x305406dd), TOBN(0x8eb7dc7f, 0xdd5d1957),
+ TOBN(0xf54a6876, 0x387d4d8f), TOBN(0x9c479409, 0xc7762de4)},
+ {TOBN(0xbe4d5b5d, 0x99b30778), TOBN(0x25380c56, 0x6e793682),
+ TOBN(0x602d37f3, 0xdac740e3), TOBN(0x140deabe, 0x1566e4ae)}},
+ {{TOBN(0x4481d067, 0xafd32acf), TOBN(0xd8f0fcca, 0xe1f71ccf),
+ TOBN(0xd208dd0c, 0xb596f2da), TOBN(0xd049d730, 0x9aad93f9)},
+ {TOBN(0xc79f263d, 0x42ab580e), TOBN(0x09411bb1, 0x23f707b4),
+ TOBN(0x8cfde1ff, 0x835e0eda), TOBN(0x72707490, 0x90f03402)}},
+ {{TOBN(0xeaee6126, 0xc49a861e), TOBN(0x024f3b65, 0xe14f0d06),
+ TOBN(0x51a3f1e8, 0xc69bfc17), TOBN(0xc3c3a8e9, 0xa7686381)},
+ {TOBN(0x3400752c, 0xb103d4c8), TOBN(0x02bc4613, 0x9218b36b),
+ TOBN(0xc67f75eb, 0x7651504a), TOBN(0xd6848b56, 0xd02aebfa)}},
+ {{TOBN(0xbd9802e6, 0xc30fa92b), TOBN(0x5a70d96d, 0x9a552784),
+ TOBN(0x9085c4ea, 0x3f83169b), TOBN(0xfa9423bb, 0x06908228)},
+ {TOBN(0x2ffebe12, 0xfe97a5b9), TOBN(0x85da6049, 0x71b99118),
+ TOBN(0x9cbc2f7f, 0x63178846), TOBN(0xfd96bc70, 0x9153218e)}},
+ {{TOBN(0x958381db, 0x1782269b), TOBN(0xae34bf79, 0x2597e550),
+ TOBN(0xbb5c6064, 0x5f385153), TOBN(0x6f0e96af, 0xe3088048)},
+ {TOBN(0xbf6a0215, 0x77884456), TOBN(0xb3b5688c, 0x69310ea7),
+ TOBN(0x17c94295, 0x04fad2de), TOBN(0xe020f0e5, 0x17896d4d)}},
+ {{TOBN(0x730ba0ab, 0x0976505f), TOBN(0x567f6813, 0x095e2ec5),
+ TOBN(0x47062010, 0x6331ab71), TOBN(0x72cfa977, 0x41d22b9f)},
+ {TOBN(0x33e55ead, 0x8a2373da), TOBN(0xa8d0d5f4, 0x7ba45a68),
+ TOBN(0xba1d8f9c, 0x03029d15), TOBN(0x8f34f1cc, 0xfc55b9f3)}},
+ {{TOBN(0xcca4428d, 0xbbe5a1a9), TOBN(0x8187fd5f, 0x3126bd67),
+ TOBN(0x0036973a, 0x48105826), TOBN(0xa39b6663, 0xb8bd61a0)},
+ {TOBN(0x6d42deef, 0x2d65a808), TOBN(0x4969044f, 0x94636b19),
+ TOBN(0xf611ee47, 0xdd5d564c), TOBN(0x7b2f3a49, 0xd2873077)}},
+ {{TOBN(0x94157d45, 0x300eb294), TOBN(0x2b2a656e, 0x169c1494),
+ TOBN(0xc000dd76, 0xd3a47aa9), TOBN(0xa2864e4f, 0xa6243ea4)},
+ {TOBN(0x82716c47, 0xdb89842e), TOBN(0x12dfd7d7, 0x61479fb7),
+ TOBN(0x3b9a2c56, 0xe0b2f6dc), TOBN(0x46be862a, 0xd7f85d67)}},
+ {{TOBN(0x03b0d8dd, 0x0f82b214), TOBN(0x460c34f9, 0xf103cbc6),
+ TOBN(0xf32e5c03, 0x18d79e19), TOBN(0x8b8888ba, 0xa84117f8)},
+ {TOBN(0x8f3c37dc, 0xc0722677), TOBN(0x10d21be9, 0x1c1c0f27),
+ TOBN(0xd47c8468, 0xe0f7a0c6), TOBN(0x9bf02213, 0xadecc0e0)}},
+ {{TOBN(0x0baa7d12, 0x42b48b99), TOBN(0x1bcb665d, 0x48424096),
+ TOBN(0x8b847cd6, 0xebfb5cfb), TOBN(0x87c2ae56, 0x9ad4d10d)},
+ {TOBN(0xf1cbb122, 0x0de36726), TOBN(0xe7043c68, 0x3fdfbd21),
+ TOBN(0x4bd0826a, 0x4e79d460), TOBN(0x11f5e598, 0x4bd1a2cb)}},
+ {{TOBN(0x97554160, 0xb7fe7b6e), TOBN(0x7d16189a, 0x400a3fb2),
+ TOBN(0xd73e9bea, 0xe328ca1e), TOBN(0x0dd04b97, 0xe793d8cc)},
+ {TOBN(0xa9c83c9b, 0x506db8cc), TOBN(0x5cd47aae, 0xcf38814c),
+ TOBN(0x26fc430d, 0xb64b45e6), TOBN(0x079b5499, 0xd818ea84)}},
+ {{TOBN(0xebb01102, 0xc1c24a3b), TOBN(0xca24e568, 0x1c161c1a),
+ TOBN(0x103eea69, 0x36f00a4a), TOBN(0x9ad76ee8, 0x76176c7b)},
+ {TOBN(0x97451fc2, 0x538e0ff7), TOBN(0x94f89809, 0x6604b3b0),
+ TOBN(0x6311436e, 0x3249cfd7), TOBN(0x27b4a7bd, 0x41224f69)}},
+ {{TOBN(0x03b5d21a, 0xe0ac2941), TOBN(0x279b0254, 0xc2d31937),
+ TOBN(0x3307c052, 0xcac992d0), TOBN(0x6aa7cb92, 0xefa8b1f3)},
+ {TOBN(0x5a182580, 0x0d37c7a5), TOBN(0x13380c37, 0x342d5422),
+ TOBN(0x92ac2d66, 0xd5d2ef92), TOBN(0x035a70c9, 0x030c63c6)}},
+ {{TOBN(0xc16025dd, 0x4ce4f152), TOBN(0x1f419a71, 0xf9df7c06),
+ TOBN(0x6d5b2214, 0x91e4bb14), TOBN(0xfc43c6cc, 0x839fb4ce)},
+ {TOBN(0x49f06591, 0x925d6b2d), TOBN(0x4b37d9d3, 0x62186598),
+ TOBN(0x8c54a971, 0xd01b1629), TOBN(0xe1a9c29f, 0x51d50e05)}},
+ {{TOBN(0x5109b785, 0x71ba1861), TOBN(0x48b22d5c, 0xd0c8f93d),
+ TOBN(0xe8fa84a7, 0x8633bb93), TOBN(0x53fba6ba, 0x5aebbd08)},
+ {TOBN(0x7ff27df3, 0xe5eea7d8), TOBN(0x521c8796, 0x68ca7158),
+ TOBN(0xb9d5133b, 0xce6f1a05), TOBN(0x2d50cd53, 0xfd0ebee4)}},
+ {{TOBN(0xc82115d6, 0xc5a3ef16), TOBN(0x993eff9d, 0xba079221),
+ TOBN(0xe4da2c5e, 0x4b5da81c), TOBN(0x9a89dbdb, 0x8033fd85)},
+ {TOBN(0x60819ebf, 0x2b892891), TOBN(0x53902b21, 0x5d14a4d5),
+ TOBN(0x6ac35051, 0xd7fda421), TOBN(0xcc6ab885, 0x61c83284)}},
+ {{TOBN(0x14eba133, 0xf74cff17), TOBN(0x240aaa03, 0xecb813f2),
+ TOBN(0xcfbb6540, 0x6f665bee), TOBN(0x084b1fe4, 0xa425ad73)},
+ {TOBN(0x009d5d16, 0xd081f6a6), TOBN(0x35304fe8, 0xeef82c90),
+ TOBN(0xf20346d5, 0xaa9eaa22), TOBN(0x0ada9f07, 0xac1c91e3)}},
+ {{TOBN(0xa6e21678, 0x968a6144), TOBN(0x54c1f77c, 0x07b31a1e),
+ TOBN(0xd6bb787e, 0x5781fbe1), TOBN(0x61bd2ee0, 0xe31f1c4a)},
+ {TOBN(0xf25aa1e9, 0x781105fc), TOBN(0x9cf2971f, 0x7b2f8e80),
+ TOBN(0x26d15412, 0xcdff919b), TOBN(0x01db4ebe, 0x34bc896e)}},
+ {{TOBN(0x7d9b3e23, 0xb40df1cf), TOBN(0x59337373, 0x94e971b4),
+ TOBN(0xbf57bd14, 0x669cf921), TOBN(0x865daedf, 0x0c1a1064)},
+ {TOBN(0x3eb70bd3, 0x83279125), TOBN(0xbc3d5b9f, 0x34ecdaab),
+ TOBN(0x91e3ed7e, 0x5f755caf), TOBN(0x49699f54, 0xd41e6f02)}},
+ {{TOBN(0x185770e1, 0xd4a7a15b), TOBN(0x08f3587a, 0xeaac87e7),
+ TOBN(0x352018db, 0x473133ea), TOBN(0x674ce719, 0x04fd30fc)},
+ {TOBN(0x7b8d9835, 0x088b3e0e), TOBN(0x7a0356a9, 0x5d0d47a1),
+ TOBN(0x9d9e7659, 0x6474a3c4), TOBN(0x61ea48a7, 0xff66966c)}},
+ {{TOBN(0x30417758, 0x0f3e4834), TOBN(0xfdbb21c2, 0x17a9afcb),
+ TOBN(0x756fa17f, 0x2f9a67b3), TOBN(0x2a6b2421, 0xa245c1a8)},
+ {TOBN(0x64be2794, 0x4af02291), TOBN(0xade465c6, 0x2a5804fe),
+ TOBN(0x8dffbd39, 0xa6f08fd7), TOBN(0xc4efa84c, 0xaa14403b)}},
+ {{TOBN(0xa1b91b2a, 0x442b0f5c), TOBN(0xb748e317, 0xcf997736),
+ TOBN(0x8d1b62bf, 0xcee90e16), TOBN(0x907ae271, 0x0b2078c0)},
+ {TOBN(0xdf31534b, 0x0c9bcddd), TOBN(0x043fb054, 0x39adce83),
+ TOBN(0x99031043, 0xd826846a), TOBN(0x61a9c0d6, 0xb144f393)}},
+ {{TOBN(0xdab48046, 0x47718427), TOBN(0xdf17ff9b, 0x6e830f8b),
+ TOBN(0x408d7ee8, 0xe49a1347), TOBN(0x6ac71e23, 0x91c1d4ae)},
+ {TOBN(0xc8cbb9fd, 0x1defd73c), TOBN(0x19840657, 0xbbbbfec5),
+ TOBN(0x39db1cb5, 0x9e7ef8ea), TOBN(0x78aa8296, 0x64105f30)}},
+ {{TOBN(0xa3d9b7f0, 0xa3738c29), TOBN(0x0a2f235a, 0xbc3250a3),
+ TOBN(0x55e506f6, 0x445e4caf), TOBN(0x0974f73d, 0x33475f7a)},
+ {TOBN(0xd37dbba3, 0x5ba2f5a8), TOBN(0x542c6e63, 0x6af40066),
+ TOBN(0x26d99b53, 0xc5d73e2c), TOBN(0x06060d7d, 0x6c3ca33e)}},
+ {{TOBN(0xcdbef1c2, 0x065fef4a), TOBN(0x77e60f7d, 0xfd5b92e3),
+ TOBN(0xd7c549f0, 0x26708350), TOBN(0x201b3ad0, 0x34f121bf)},
+ {TOBN(0x5fcac2a1, 0x0334fc14), TOBN(0x8a9a9e09, 0x344552f6),
+ TOBN(0x7dd8a1d3, 0x97653082), TOBN(0x5fc0738f, 0x79d4f289)}},
+ {{TOBN(0x787d244d, 0x17d2d8c3), TOBN(0xeffc6345, 0x70830684),
+ TOBN(0x5ddb96dd, 0xe4f73ae5), TOBN(0x8efb14b1, 0x172549a5)},
+ {TOBN(0x6eb73eee, 0x2245ae7a), TOBN(0xbca4061e, 0xea11f13e),
+ TOBN(0xb577421d, 0x30b01f5d), TOBN(0xaa688b24, 0x782e152c)}},
+ {{TOBN(0x67608e71, 0xbd3502ba), TOBN(0x4ef41f24, 0xb4de75a0),
+ TOBN(0xb08dde5e, 0xfd6125e5), TOBN(0xde484825, 0xa409543f)},
+ {TOBN(0x1f198d98, 0x65cc2295), TOBN(0x428a3771, 0x6e0edfa2),
+ TOBN(0x4f9697a2, 0xadf35fc7), TOBN(0x01a43c79, 0xf7cac3c7)}},
+ {{TOBN(0xb05d7059, 0x0fd3659a), TOBN(0x8927f30c, 0xbb7f2d9a),
+ TOBN(0x4023d1ac, 0x8cf984d3), TOBN(0x32125ed3, 0x02897a45)},
+ {TOBN(0xfb572dad, 0x3d414205), TOBN(0x73000ef2, 0xe3fa82a9),
+ TOBN(0x4c0868e9, 0xf10a5581), TOBN(0x5b61fc67, 0x6b0b3ca5)}},
+ {{TOBN(0xc1258d5b, 0x7cae440c), TOBN(0x21c08b41, 0x402b7531),
+ TOBN(0xf61a8955, 0xde932321), TOBN(0x3568faf8, 0x2d1408af)},
+ {TOBN(0x71b15e99, 0x9ecf965b), TOBN(0xf14ed248, 0xe917276f),
+ TOBN(0xc6f4caa1, 0x820cf9e2), TOBN(0x681b20b2, 0x18d83c7e)}},
+ {{TOBN(0x6cde738d, 0xc6c01120), TOBN(0x71db0813, 0xae70e0db),
+ TOBN(0x95fc0644, 0x74afe18c), TOBN(0x34619053, 0x129e2be7)},
+ {TOBN(0x80615cea, 0xdb2a3b15), TOBN(0x0a49a19e, 0xdb4c7073),
+ TOBN(0x0e1b84c8, 0x8fd2d367), TOBN(0xd74bf462, 0x033fb8aa)}},
+ {{TOBN(0x889f6d65, 0x533ef217), TOBN(0x7158c7e4, 0xc3ca2e87),
+ TOBN(0xfb670dfb, 0xdc2b4167), TOBN(0x75910a01, 0x844c257f)},
+ {TOBN(0xf336bf07, 0xcf88577d), TOBN(0x22245250, 0xe45e2ace),
+ TOBN(0x2ed92e8d, 0x7ca23d85), TOBN(0x29f8be4c, 0x2b812f58)}},
+ {{TOBN(0xdd9ebaa7, 0x076fe12b), TOBN(0x3f2400cb, 0xae1537f9),
+ TOBN(0x1aa93528, 0x17bdfb46), TOBN(0xc0f98430, 0x67883b41)},
+ {TOBN(0x5590ede1, 0x0170911d), TOBN(0x7562f5bb, 0x34d4b17f),
+ TOBN(0xe1fa1df2, 0x1826b8d2), TOBN(0xb40b796a, 0x6bd80d59)}},
+ {{TOBN(0xd65bf197, 0x3467ba92), TOBN(0x8c9b46db, 0xf70954b0),
+ TOBN(0x97c8a0f3, 0x0e78f15d), TOBN(0xa8f3a69a, 0x85a4c961)},
+ {TOBN(0x4242660f, 0x61e4ce9b), TOBN(0xbf06aab3, 0x6ea6790c),
+ TOBN(0xc6706f8e, 0xec986416), TOBN(0x9e56dec1, 0x9a9fc225)}},
+ {{TOBN(0x527c46f4, 0x9a9898d9), TOBN(0xd799e77b, 0x5633cdef),
+ TOBN(0x24eacc16, 0x7d9e4297), TOBN(0xabb61cea, 0x6b1cb734)},
+ {TOBN(0xbee2e8a7, 0xf778443c), TOBN(0x3bb42bf1, 0x29de2fe6),
+ TOBN(0xcbed86a1, 0x3003bb6f), TOBN(0xd3918e6c, 0xd781cdf6)}},
+ {{TOBN(0x4bee3271, 0x9a5103f1), TOBN(0x5243efc6, 0xf50eac06),
+ TOBN(0xb8e122cb, 0x6adcc119), TOBN(0x1b7faa84, 0xc0b80a08)},
+ {TOBN(0x32c3d1bd, 0x6dfcd08c), TOBN(0x129dec4e, 0x0be427de),
+ TOBN(0x98ab679c, 0x1d263c83), TOBN(0xafc83cb7, 0xcef64eff)}},
+ {{TOBN(0x85eb6088, 0x2fa6be76), TOBN(0x892585fb, 0x1328cbfe),
+ TOBN(0xc154d3ed, 0xcf618dda), TOBN(0xc44f601b, 0x3abaf26e)},
+ {TOBN(0x7bf57d0b, 0x2be1fdfd), TOBN(0xa833bd2d, 0x21137fee),
+ TOBN(0x9353af36, 0x2db591a8), TOBN(0xc76f26dc, 0x5562a056)}},
+ {{TOBN(0x1d87e47d, 0x3fdf5a51), TOBN(0x7afb5f93, 0x55c9cab0),
+ TOBN(0x91bbf58f, 0x89e0586e), TOBN(0x7c72c018, 0x0d843709)},
+ {TOBN(0xa9a5aafb, 0x99b5c3dc), TOBN(0xa48a0f1d, 0x3844aeb0),
+ TOBN(0x7178b7dd, 0xb667e482), TOBN(0x453985e9, 0x6e23a59a)}},
+ {{TOBN(0x4a54c860, 0x01b25dd8), TOBN(0x0dd37f48, 0xfb897c8a),
+ TOBN(0x5f8aa610, 0x0ea90cd9), TOBN(0xc8892c68, 0x16d5830d)},
+ {TOBN(0xeb4befc0, 0xef514ca5), TOBN(0x478eb679, 0xe72c9ee6),
+ TOBN(0x9bca20da, 0xdbc40d5f), TOBN(0xf015de21, 0xdde4f64a)}},
+ {{TOBN(0xaa6a4de0, 0xeaf4b8a5), TOBN(0x68cfd9ca, 0x4bc60e32),
+ TOBN(0x668a4b01, 0x7fd15e70), TOBN(0xd9f0694a, 0xf27dc09d)},
+ {TOBN(0xf6c3cad5, 0xba708bcd), TOBN(0x5cd2ba69, 0x5bb95c2a),
+ TOBN(0xaa28c1d3, 0x33c0a58f), TOBN(0x23e274e3, 0xabc77870)}},
+ {{TOBN(0x44c3692d, 0xdfd20a4a), TOBN(0x091c5fd3, 0x81a66653),
+ TOBN(0x6c0bb691, 0x09a0757d), TOBN(0x9072e8b9, 0x667343ea)},
+ {TOBN(0x31d40eb0, 0x80848bec), TOBN(0x95bd480a, 0x79fd36cc),
+ TOBN(0x01a77c61, 0x65ed43f5), TOBN(0xafccd127, 0x2e0d40bf)}},
+ {{TOBN(0xeccfc82d, 0x1cc1884b), TOBN(0xc85ac201, 0x5d4753b4),
+ TOBN(0xc7a6caac, 0x658e099f), TOBN(0xcf46369e, 0x04b27390)},
+ {TOBN(0xe2e7d049, 0x506467ea), TOBN(0x481b63a2, 0x37cdeccc),
+ TOBN(0x4029abd8, 0xed80143a), TOBN(0x28bfe3c7, 0xbcb00b88)}},
+ {{TOBN(0x3bec1009, 0x0643d84a), TOBN(0x885f3668, 0xabd11041),
+ TOBN(0xdb02432c, 0xf83a34d6), TOBN(0x32f7b360, 0x719ceebe)},
+ {TOBN(0xf06c7837, 0xdad1fe7a), TOBN(0x60a157a9, 0x5441a0b0),
+ TOBN(0x704970e9, 0xe2d47550), TOBN(0xcd2bd553, 0x271b9020)}},
+ {{TOBN(0xff57f82f, 0x33e24a0b), TOBN(0x9cbee23f, 0xf2565079),
+ TOBN(0x16353427, 0xeb5f5825), TOBN(0x276feec4, 0xe948d662)},
+ {TOBN(0xd1b62bc6, 0xda10032b), TOBN(0x718351dd, 0xf0e72a53),
+ TOBN(0x93452076, 0x2420e7ba), TOBN(0x96368fff, 0x3a00118d)}},
+ {{TOBN(0x00ce2d26, 0x150a49e4), TOBN(0x0c28b636, 0x3f04706b),
+ TOBN(0xbad65a46, 0x58b196d0), TOBN(0x6c8455fc, 0xec9f8b7c)},
+ {TOBN(0xe90c895f, 0x2d71867e), TOBN(0x5c0be31b, 0xedf9f38c),
+ TOBN(0x2a37a15e, 0xd8f6ec04), TOBN(0x239639e7, 0x8cd85251)}},
+ {{TOBN(0xd8975315, 0x9c7c4c6b), TOBN(0x603aa3c0, 0xd7409af7),
+ TOBN(0xb8d53d0c, 0x007132fb), TOBN(0x68d12af7, 0xa6849238)},
+ {TOBN(0xbe0607e7, 0xbf5d9279), TOBN(0x9aa50055, 0xaada74ce),
+ TOBN(0xe81079cb, 0xba7e8ccb), TOBN(0x610c71d1, 0xa5f4ff5e)}},
+ {{TOBN(0x9e2ee1a7, 0x5aa07093), TOBN(0xca84004b, 0xa75da47c),
+ TOBN(0x074d3951, 0x3de75401), TOBN(0xf938f756, 0xbb311592)},
+ {TOBN(0x96197618, 0x00a43421), TOBN(0x39a25362, 0x07bc78c8),
+ TOBN(0x278f710a, 0x0a171276), TOBN(0xb28446ea, 0x8d1a8f08)}},
+ {{TOBN(0x184781bf, 0xe3b6a661), TOBN(0x7751cb1d, 0xe6d279f7),
+ TOBN(0xf8ff95d6, 0xc59eb662), TOBN(0x186d90b7, 0x58d3dea7)},
+ {TOBN(0x0e4bb6c1, 0xdfb4f754), TOBN(0x5c5cf56b, 0x2b2801dc),
+ TOBN(0xc561e452, 0x1f54564d), TOBN(0xb4fb8c60, 0xf0dd7f13)}},
+ {{TOBN(0xf8849630, 0x33ff98c7), TOBN(0x9619fffa, 0xcf17769c),
+ TOBN(0xf8090bf6, 0x1bfdd80a), TOBN(0x14d9a149, 0x422cfe63)},
+ {TOBN(0xb354c360, 0x6f6df9ea), TOBN(0xdbcf770d, 0x218f17ea),
+ TOBN(0x207db7c8, 0x79eb3480), TOBN(0x213dbda8, 0x559b6a26)}},
+ {{TOBN(0xac4c200b, 0x29fc81b3), TOBN(0xebc3e09f, 0x171d87c1),
+ TOBN(0x91799530, 0x1481aa9e), TOBN(0x051b92e1, 0x92e114fa)},
+ {TOBN(0xdf8f92e9, 0xecb5537f), TOBN(0x44b1b2cc, 0x290c7483),
+ TOBN(0xa711455a, 0x2adeb016), TOBN(0x964b6856, 0x81a10c2c)}},
+ {{TOBN(0x4f159d99, 0xcec03623), TOBN(0x05532225, 0xef3271ea),
+ TOBN(0xb231bea3, 0xc5ee4849), TOBN(0x57a54f50, 0x7094f103)},
+ {TOBN(0x3e2d421d, 0x9598b352), TOBN(0xe865a49c, 0x67412ab4),
+ TOBN(0xd2998a25, 0x1cc3a912), TOBN(0x5d092808, 0x0c74d65d)}},
+ {{TOBN(0x73f45908, 0x4088567a), TOBN(0xeb6b280e, 0x1f214a61),
+ TOBN(0x8c9adc34, 0xcaf0c13d), TOBN(0x39d12938, 0xf561fb80)},
+ {TOBN(0xb2dc3a5e, 0xbc6edfb4), TOBN(0x7485b1b1, 0xfe4d210e),
+ TOBN(0x062e0400, 0xe186ae72), TOBN(0x91e32d5c, 0x6eeb3b88)}},
+ {{TOBN(0x6df574d7, 0x4be59224), TOBN(0xebc88ccc, 0x716d55f3),
+ TOBN(0x26c2e6d0, 0xcad6ed33), TOBN(0xc6e21e7d, 0x0d3e8b10)},
+ {TOBN(0x2cc5840e, 0x5bcc36bb), TOBN(0x9292445e, 0x7da74f69),
+ TOBN(0x8be8d321, 0x4e5193a8), TOBN(0x3ec23629, 0x8df06413)}},
+ {{TOBN(0xc7e9ae85, 0xb134defa), TOBN(0x6073b1d0, 0x1bb2d475),
+ TOBN(0xb9ad615e, 0x2863c00d), TOBN(0x9e29493d, 0x525f4ac4)},
+ {TOBN(0xc32b1dea, 0x4e9acf4f), TOBN(0x3e1f01c8, 0xa50db88d),
+ TOBN(0xb05d70ea, 0x04da916c), TOBN(0x714b0d0a, 0xd865803e)}},
+ {{TOBN(0x4bd493fc, 0x9920cb5e), TOBN(0x5b44b1f7, 0x92c7a3ac),
+ TOBN(0xa2a77293, 0xbcec9235), TOBN(0x5ee06e87, 0xcd378553)},
+ {TOBN(0xceff8173, 0xda621607), TOBN(0x2bb03e4c, 0x99f5d290),
+ TOBN(0x2945106a, 0xa6f734ac), TOBN(0xb5056604, 0xd25c4732)}},
+ {{TOBN(0x5945920c, 0xe079afee), TOBN(0x686e17a0, 0x6789831f),
+ TOBN(0x5966bee8, 0xb74a5ae5), TOBN(0x38a673a2, 0x1e258d46)},
+ {TOBN(0xbd1cc1f2, 0x83141c95), TOBN(0x3b2ecf4f, 0x0e96e486),
+ TOBN(0xcd3aa896, 0x74e5fc78), TOBN(0x415ec10c, 0x2482fa7a)}},
+ {{TOBN(0x15234419, 0x80503380), TOBN(0x513d917a, 0xd314b392),
+ TOBN(0xb0b52f4e, 0x63caecae), TOBN(0x07bf22ad, 0x2dc7780b)},
+ {TOBN(0xe761e8a1, 0xe4306839), TOBN(0x1b3be962, 0x5dd7feaa),
+ TOBN(0x4fe728de, 0x74c778f1), TOBN(0xf1fa0bda, 0x5e0070f6)}},
+ {{TOBN(0x85205a31, 0x6ec3f510), TOBN(0x2c7e4a14, 0xd2980475),
+ TOBN(0xde3c19c0, 0x6f30ebfd), TOBN(0xdb1c1f38, 0xd4b7e644)},
+ {TOBN(0xfe291a75, 0x5dce364a), TOBN(0xb7b22a3c, 0x058f5be3),
+ TOBN(0x2cd2c302, 0x37fea38c), TOBN(0x2930967a, 0x2e17be17)}},
+ {{TOBN(0x87f009de, 0x0c061c65), TOBN(0xcb014aac, 0xedc6ed44),
+ TOBN(0x49bd1cb4, 0x3bafb1eb), TOBN(0x81bd8b5c, 0x282d3688)},
+ {TOBN(0x1cdab87e, 0xf01a17af), TOBN(0x21f37ac4, 0xe710063b),
+ TOBN(0x5a6c5676, 0x42fc8193), TOBN(0xf4753e70, 0x56a6015c)}},
+ {{TOBN(0x020f795e, 0xa15b0a44), TOBN(0x8f37c8d7, 0x8958a958),
+ TOBN(0x63b7e89b, 0xa4b675b5), TOBN(0xb4fb0c0c, 0x0fc31aea)},
+ {TOBN(0xed95e639, 0xa7ff1f2e), TOBN(0x9880f5a3, 0x619614fb),
+ TOBN(0xdeb6ff02, 0x947151ab), TOBN(0x5bc5118c, 0xa868dcdb)}},
+ {{TOBN(0xd8da2055, 0x4c20cea5), TOBN(0xcac2776e, 0x14c4d69a),
+ TOBN(0xcccb22c1, 0x622d599b), TOBN(0xa4ddb653, 0x68a9bb50)},
+ {TOBN(0x2c4ff151, 0x1b4941b4), TOBN(0xe1ff19b4, 0x6efba588),
+ TOBN(0x35034363, 0xc48345e0), TOBN(0x45542e3d, 0x1e29dfc4)}},
+ {{TOBN(0xf197cb91, 0x349f7aed), TOBN(0x3b2b5a00, 0x8fca8420),
+ TOBN(0x7c175ee8, 0x23aaf6d8), TOBN(0x54dcf421, 0x35af32b6)},
+ {TOBN(0x0ba14307, 0x27d6561e), TOBN(0x879d5ee4, 0xd175b1e2),
+ TOBN(0xc7c43673, 0x99807db5), TOBN(0x77a54455, 0x9cd55bcd)}},
+ {{TOBN(0xe6c2ff13, 0x0105c072), TOBN(0x18f7a99f, 0x8dda7da4),
+ TOBN(0x4c301820, 0x0e2d35c1), TOBN(0x06a53ca0, 0xd9cc6c82)},
+ {TOBN(0xaa21cc1e, 0xf1aa1d9e), TOBN(0x32414334, 0x4a75b1e8),
+ TOBN(0x2a6d1328, 0x0ebe9fdc), TOBN(0x16bd173f, 0x98a4755a)}},
+ {{TOBN(0xfbb9b245, 0x2133ffd9), TOBN(0x39a8b2f1, 0x830f1a20),
+ TOBN(0x484bc97d, 0xd5a1f52a), TOBN(0xd6aebf56, 0xa40eddf8)},
+ {TOBN(0x32257acb, 0x76ccdac6), TOBN(0xaf4d36ec, 0x1586ff27),
+ TOBN(0x8eaa8863, 0xf8de7dd1), TOBN(0x0045d5cf, 0x88647c16)}}},
+ {{{TOBN(0xa6f3d574, 0xc005979d), TOBN(0xc2072b42, 0x6a40e350),
+ TOBN(0xfca5c156, 0x8de2ecf9), TOBN(0xa8c8bf5b, 0xa515344e)},
+ {TOBN(0x97aee555, 0x114df14a), TOBN(0xd4374a4d, 0xfdc5ec6b),
+ TOBN(0x754cc28f, 0x2ca85418), TOBN(0x71cb9e27, 0xd3c41f78)}},
+ {{TOBN(0x89105079, 0x03605c39), TOBN(0xf0843d9e, 0xa142c96c),
+ TOBN(0xf3744934, 0x16923684), TOBN(0x732caa2f, 0xfa0a2893)},
+ {TOBN(0xb2e8c270, 0x61160170), TOBN(0xc32788cc, 0x437fbaa3),
+ TOBN(0x39cd818e, 0xa6eda3ac), TOBN(0xe2e94239, 0x9e2b2e07)}},
+ {{TOBN(0x6967d39b, 0x0260e52a), TOBN(0xd42585cc, 0x90653325),
+ TOBN(0x0d9bd605, 0x21ca7954), TOBN(0x4fa20877, 0x81ed57b3)},
+ {TOBN(0x60c1eff8, 0xe34a0bbe), TOBN(0x56b0040c, 0x84f6ef64),
+ TOBN(0x28be2b24, 0xb1af8483), TOBN(0xb2278163, 0xf5531614)}},
+ {{TOBN(0x8df27545, 0x5922ac1c), TOBN(0xa7b3ef5c, 0xa52b3f63),
+ TOBN(0x8e77b214, 0x71de57c4), TOBN(0x31682c10, 0x834c008b)},
+ {TOBN(0xc76824f0, 0x4bd55d31), TOBN(0xb6d1c086, 0x17b61c71),
+ TOBN(0x31db0903, 0xc2a5089d), TOBN(0x9c092172, 0x184e5d3f)}},
+ {{TOBN(0xdd7ced5b, 0xc00cc638), TOBN(0x1a2015eb, 0x61278fc2),
+ TOBN(0x2e8e5288, 0x6a37f8d6), TOBN(0xc457786f, 0xe79933ad)},
+ {TOBN(0xb3fe4cce, 0x2c51211a), TOBN(0xad9b10b2, 0x24c20498),
+ TOBN(0x90d87a4f, 0xd28db5e5), TOBN(0x698cd105, 0x3aca2fc3)}},
+ {{TOBN(0x4f112d07, 0xe91b536d), TOBN(0xceb982f2, 0x9eba09d6),
+ TOBN(0x3c157b2c, 0x197c396f), TOBN(0xe23c2d41, 0x7b66eb24)},
+ {TOBN(0x480c57d9, 0x3f330d37), TOBN(0xb3a4c8a1, 0x79108deb),
+ TOBN(0x702388de, 0xcb199ce5), TOBN(0x0b019211, 0xb944a8d4)}},
+ {{TOBN(0x24f2a692, 0x840bb336), TOBN(0x7c353bdc, 0xa669fa7b),
+ TOBN(0xda20d6fc, 0xdec9c300), TOBN(0x625fbe2f, 0xa13a4f17)},
+ {TOBN(0xa2b1b61a, 0xdbc17328), TOBN(0x008965bf, 0xa9515621),
+ TOBN(0x49690939, 0xc620ff46), TOBN(0x182dd27d, 0x8717e91c)}},
+ {{TOBN(0x5ace5035, 0xea6c3997), TOBN(0x54259aaa, 0xc2610bef),
+ TOBN(0xef18bb3f, 0x3c80dd39), TOBN(0x6910b95b, 0x5fc3fa39)},
+ {TOBN(0xfce2f510, 0x43e09aee), TOBN(0xced56c9f, 0xa7675665),
+ TOBN(0x10e265ac, 0xd872db61), TOBN(0x6982812e, 0xae9fce69)}},
+ {{TOBN(0x29be11c6, 0xce800998), TOBN(0x72bb1752, 0xb90360d9),
+ TOBN(0x2c193197, 0x5a4ad590), TOBN(0x2ba2f548, 0x9fc1dbc0)},
+ {TOBN(0x7fe4eebb, 0xe490ebe0), TOBN(0x12a0a4cd, 0x7fae11c0),
+ TOBN(0x7197cf81, 0xe903ba37), TOBN(0xcf7d4aa8, 0xde1c6dd8)}},
+ {{TOBN(0x92af6bf4, 0x3fd5684c), TOBN(0x2b26eecf, 0x80360aa1),
+ TOBN(0xbd960f30, 0x00546a82), TOBN(0x407b3c43, 0xf59ad8fe)},
+ {TOBN(0x86cae5fe, 0x249c82ba), TOBN(0x9e0faec7, 0x2463744c),
+ TOBN(0x87f551e8, 0x94916272), TOBN(0x033f9344, 0x6ceb0615)}},
+ {{TOBN(0x1e5eb0d1, 0x8be82e84), TOBN(0x89967f0e, 0x7a582fef),
+ TOBN(0xbcf687d5, 0xa6e921fa), TOBN(0xdfee4cf3, 0xd37a09ba)},
+ {TOBN(0x94f06965, 0xb493c465), TOBN(0x638b9a1c, 0x7635c030),
+ TOBN(0x76667864, 0x66f05e9f), TOBN(0xccaf6808, 0xc04da725)}},
+ {{TOBN(0xca2eb690, 0x768fccfc), TOBN(0xf402d37d, 0xb835b362),
+ TOBN(0x0efac0d0, 0xe2fdfcce), TOBN(0xefc9cdef, 0xb638d990)},
+ {TOBN(0x2af12b72, 0xd1669a8b), TOBN(0x33c536bc, 0x5774ccbd),
+ TOBN(0x30b21909, 0xfb34870e), TOBN(0xc38fa2f7, 0x7df25aca)}},
+ {{TOBN(0x74c5f02b, 0xbf81f3f5), TOBN(0x0525a5ae, 0xaf7e4581),
+ TOBN(0x88d2aaba, 0x433c54ae), TOBN(0xed9775db, 0x806a56c5)},
+ {TOBN(0xd320738a, 0xc0edb37d), TOBN(0x25fdb6ee, 0x66cc1f51),
+ TOBN(0xac661d17, 0x10600d76), TOBN(0x931ec1f3, 0xbdd1ed76)}},
+ {{TOBN(0x65c11d62, 0x19ee43f1), TOBN(0x5cd57c3e, 0x60829d97),
+ TOBN(0xd26c91a3, 0x984be6e8), TOBN(0xf08d9309, 0x8b0c53bd)},
+ {TOBN(0x94bc9e5b, 0xc016e4ea), TOBN(0xd3916839, 0x11d43d2b),
+ TOBN(0x886c5ad7, 0x73701155), TOBN(0xe0377626, 0x20b00715)}},
+ {{TOBN(0x7f01c9ec, 0xaa80ba59), TOBN(0x3083411a, 0x68538e51),
+ TOBN(0x970370f1, 0xe88128af), TOBN(0x625cc3db, 0x91dec14b)},
+ {TOBN(0xfef9666c, 0x01ac3107), TOBN(0xb2a8d577, 0xd5057ac3),
+ TOBN(0xb0f26299, 0x92be5df7), TOBN(0xf579c8e5, 0x00353924)}},
+ {{TOBN(0xb8fa3d93, 0x1341ed7a), TOBN(0x4223272c, 0xa7b59d49),
+ TOBN(0x3dcb1947, 0x83b8c4a4), TOBN(0x4e413c01, 0xed1302e4)},
+ {TOBN(0x6d999127, 0xe17e44ce), TOBN(0xee86bf75, 0x33b3adfb),
+ TOBN(0xf6902fe6, 0x25aa96ca), TOBN(0xb73540e4, 0xe5aae47d)}},
+ {{TOBN(0x32801d7b, 0x1b4a158c), TOBN(0xe571c99e, 0x27e2a369),
+ TOBN(0x40cb76c0, 0x10d9f197), TOBN(0xc308c289, 0x3167c0ae)},
+ {TOBN(0xa6ef9dd3, 0xeb7958f2), TOBN(0xa7226dfc, 0x300879b1),
+ TOBN(0x6cd0b362, 0x7edf0636), TOBN(0x4efbce6c, 0x7bc37eed)}},
+ {{TOBN(0x75f92a05, 0x8d699021), TOBN(0x586d4c79, 0x772566e3),
+ TOBN(0x378ca5f1, 0x761ad23a), TOBN(0x650d86fc, 0x1465a8ac)},
+ {TOBN(0x7a4ed457, 0x842ba251), TOBN(0x6b65e3e6, 0x42234933),
+ TOBN(0xaf1543b7, 0x31aad657), TOBN(0xa4cefe98, 0xcbfec369)}},
+ {{TOBN(0xb587da90, 0x9f47befb), TOBN(0x6562e9fb, 0x41312d13),
+ TOBN(0xa691ea59, 0xeff1cefe), TOBN(0xcc30477a, 0x05fc4cf6)},
+ {TOBN(0xa1632461, 0x0b0ffd3d), TOBN(0xa1f16f3b, 0x5b355956),
+ TOBN(0x5b148d53, 0x4224ec24), TOBN(0xdc834e7b, 0xf977012a)}},
+ {{TOBN(0x7bfc5e75, 0xb2c69dbc), TOBN(0x3aa77a29, 0x03c3da6c),
+ TOBN(0xde0df03c, 0xca910271), TOBN(0xcbd5ca4a, 0x7806dc55)},
+ {TOBN(0xe1ca5807, 0x6db476cb), TOBN(0xfde15d62, 0x5f37a31e),
+ TOBN(0xf49af520, 0xf41af416), TOBN(0x96c5c5b1, 0x7d342db5)}},
+ {{TOBN(0x155c43b7, 0xeb4ceb9b), TOBN(0x2e993010, 0x4e77371a),
+ TOBN(0x1d2987da, 0x675d43af), TOBN(0xef2bc1c0, 0x8599fd72)},
+ {TOBN(0x96894b7b, 0x9342f6b2), TOBN(0x201eadf2, 0x7c8e71f0),
+ TOBN(0xf3479d9f, 0x4a1f3efc), TOBN(0xe0f8a742, 0x702a9704)}},
+ {{TOBN(0xeafd44b6, 0xb3eba40c), TOBN(0xf9739f29, 0xc1c1e0d0),
+ TOBN(0x0091471a, 0x619d505e), TOBN(0xc15f9c96, 0x9d7c263e)},
+ {TOBN(0x5be47285, 0x83afbe33), TOBN(0xa3b6d6af, 0x04f1e092),
+ TOBN(0xe76526b9, 0x751a9d11), TOBN(0x2ec5b26d, 0x9a4ae4d2)}},
+ {{TOBN(0xeb66f4d9, 0x02f6fb8d), TOBN(0x4063c561, 0x96912164),
+ TOBN(0xeb7050c1, 0x80ef3000), TOBN(0x288d1c33, 0xeaa5b3f0)},
+ {TOBN(0xe87c68d6, 0x07806fd8), TOBN(0xb2f7f9d5, 0x4bbbf50f),
+ TOBN(0x25972f3a, 0xac8d6627), TOBN(0xf8547774, 0x10e8c13b)}},
+ {{TOBN(0xcc50ef6c, 0x872b4a60), TOBN(0xab2a34a4, 0x4613521b),
+ TOBN(0x39c5c190, 0x983e15d1), TOBN(0x61dde5df, 0x59905512)},
+ {TOBN(0xe417f621, 0x9f2275f3), TOBN(0x0750c8b6, 0x451d894b),
+ TOBN(0x75b04ab9, 0x78b0bdaa), TOBN(0x3bfd9fd4, 0x458589bd)}},
+ {{TOBN(0xf1013e30, 0xee9120b6), TOBN(0x2b51af93, 0x23a4743e),
+ TOBN(0xea96ffae, 0x48d14d9e), TOBN(0x71dc0dbe, 0x698a1d32)},
+ {TOBN(0x914962d2, 0x0180cca4), TOBN(0x1ae60677, 0xc3568963),
+ TOBN(0x8cf227b1, 0x437bc444), TOBN(0xc650c83b, 0xc9962c7a)}},
+ {{TOBN(0x23c2c7dd, 0xfe7ccfc4), TOBN(0xf925c89d, 0x1b929d48),
+ TOBN(0x4460f74b, 0x06783c33), TOBN(0xac2c8d49, 0xa590475a)},
+ {TOBN(0xfb40b407, 0xb807bba0), TOBN(0x9d1e362d, 0x69ff8f3a),
+ TOBN(0xa33e9681, 0xcbef64a4), TOBN(0x67ece5fa, 0x332fb4b2)}},
+ {{TOBN(0x6900a99b, 0x739f10e3), TOBN(0xc3341ca9, 0xff525925),
+ TOBN(0xee18a626, 0xa9e2d041), TOBN(0xa5a83685, 0x29580ddd)},
+ {TOBN(0xf3470c81, 0x9d7de3cd), TOBN(0xedf02586, 0x2062cf9c),
+ TOBN(0xf43522fa, 0xc010edb0), TOBN(0x30314135, 0x13a4b1ae)}},
+ {{TOBN(0xc792e02a, 0xdb22b94b), TOBN(0x993d8ae9, 0xa1eaa45b),
+ TOBN(0x8aad6cd3, 0xcd1e1c63), TOBN(0x89529ca7, 0xc5ce688a)},
+ {TOBN(0x2ccee3aa, 0xe572a253), TOBN(0xe02b6438, 0x02a21efb),
+ TOBN(0xa7091b6e, 0xc9430358), TOBN(0x06d1b1fa, 0x9d7db504)}},
+ {{TOBN(0x58846d32, 0xc4744733), TOBN(0x40517c71, 0x379f9e34),
+ TOBN(0x2f65655f, 0x130ef6ca), TOBN(0x526e4488, 0xf1f3503f)},
+ {TOBN(0x8467bd17, 0x7ee4a976), TOBN(0x1d9dc913, 0x921363d1),
+ TOBN(0xd8d24c33, 0xb069e041), TOBN(0x5eb5da0a, 0x2cdf7f51)}},
+ {{TOBN(0x1c0f3cb1, 0x197b994f), TOBN(0x3c95a6c5, 0x2843eae9),
+ TOBN(0x7766ffc9, 0xa6097ea5), TOBN(0x7bea4093, 0xd723b867)},
+ {TOBN(0xb48e1f73, 0x4db378f9), TOBN(0x70025b00, 0xe37b77ac),
+ TOBN(0x943dc8e7, 0xaf24ad46), TOBN(0xb98a15ac, 0x16d00a85)}},
+ {{TOBN(0x3adc38ba, 0x2743b004), TOBN(0xb1c7f4f7, 0x334415ee),
+ TOBN(0xea43df8f, 0x1e62d05a), TOBN(0x32618905, 0x9d76a3b6)},
+ {TOBN(0x2fbd0bb5, 0xa23a0f46), TOBN(0x5bc971db, 0x6a01918c),
+ TOBN(0x7801d94a, 0xb4743f94), TOBN(0xb94df65e, 0x676ae22b)}},
+ {{TOBN(0xaafcbfab, 0xaf95894c), TOBN(0x7b9bdc07, 0x276b2241),
+ TOBN(0xeaf98362, 0x5bdda48b), TOBN(0x5977faf2, 0xa3fcb4df)},
+ {TOBN(0xbed042ef, 0x052c4b5b), TOBN(0x9fe87f71, 0x067591f0),
+ TOBN(0xc89c73ca, 0x22f24ec7), TOBN(0x7d37fa9e, 0xe64a9f1b)}},
+ {{TOBN(0x2710841a, 0x15562627), TOBN(0x2c01a613, 0xc243b034),
+ TOBN(0x1d135c56, 0x2bc68609), TOBN(0xc2ca1715, 0x8b03f1f6)},
+ {TOBN(0xc9966c2d, 0x3eb81d82), TOBN(0xc02abf4a, 0x8f6df13e),
+ TOBN(0x77b34bd7, 0x8f72b43b), TOBN(0xaff6218f, 0x360c82b0)}},
+ {{TOBN(0x0aa5726c, 0x8d55b9d2), TOBN(0xdc0adbe9, 0x99e9bffb),
+ TOBN(0x9097549c, 0xefb9e72a), TOBN(0x16755712, 0x9dfb3111)},
+ {TOBN(0xdd8bf984, 0xf26847f9), TOBN(0xbcb8e387, 0xdfb30cb7),
+ TOBN(0xc1fd32a7, 0x5171ef9c), TOBN(0x977f3fc7, 0x389b363f)}},
+ {{TOBN(0x116eaf2b, 0xf4babda0), TOBN(0xfeab68bd, 0xf7113c8e),
+ TOBN(0xd1e3f064, 0xb7def526), TOBN(0x1ac30885, 0xe0b3fa02)},
+ {TOBN(0x1c5a6e7b, 0x40142d9d), TOBN(0x839b5603, 0x30921c0b),
+ TOBN(0x48f301fa, 0x36a116a3), TOBN(0x380e1107, 0xcfd9ee6d)}},
+ {{TOBN(0x7945ead8, 0x58854be1), TOBN(0x4111c12e, 0xcbd4d49d),
+ TOBN(0xece3b1ec, 0x3a29c2ef), TOBN(0x6356d404, 0x8d3616f5)},
+ {TOBN(0x9f0d6a8f, 0x594d320e), TOBN(0x0989316d, 0xf651ccd2),
+ TOBN(0x6c32117a, 0x0f8fdde4), TOBN(0x9abe5cc5, 0xa26a9bbc)}},
+ {{TOBN(0xcff560fb, 0x9723f671), TOBN(0x21b2a12d, 0x7f3d593c),
+ TOBN(0xe4cb18da, 0x24ba0696), TOBN(0x186e2220, 0xc3543384)},
+ {TOBN(0x722f64e0, 0x88312c29), TOBN(0x94282a99, 0x17dc7752),
+ TOBN(0x62467bbf, 0x5a85ee89), TOBN(0xf435c650, 0xf10076a0)}},
+ {{TOBN(0xc9ff1539, 0x43b3a50b), TOBN(0x7132130c, 0x1a53efbc),
+ TOBN(0x31bfe063, 0xf7b0c5b7), TOBN(0xb0179a7d, 0x4ea994cc)},
+ {TOBN(0x12d064b3, 0xc85f455b), TOBN(0x47259328, 0x8f6e0062),
+ TOBN(0xf64e590b, 0xb875d6d9), TOBN(0x22dd6225, 0xad92bcc7)}},
+ {{TOBN(0xb658038e, 0xb9c3bd6d), TOBN(0x00cdb0d6, 0xfbba27c8),
+ TOBN(0x0c681337, 0x1062c45d), TOBN(0xd8515b8c, 0x2d33407d)},
+ {TOBN(0xcb8f699e, 0x8cbb5ecf), TOBN(0x8c4347f8, 0xc608d7d8),
+ TOBN(0x2c11850a, 0xbb3e00db), TOBN(0x20a8dafd, 0xecb49d19)}},
+ {{TOBN(0xbd781480, 0x45ee2f40), TOBN(0x75e354af, 0x416b60cf),
+ TOBN(0xde0b58a1, 0x8d49a8c4), TOBN(0xe40e94e2, 0xfa359536)},
+ {TOBN(0xbd4fa59f, 0x62accd76), TOBN(0x05cf466a, 0x8c762837),
+ TOBN(0xb5abda99, 0x448c277b), TOBN(0x5a9e01bf, 0x48b13740)}},
+ {{TOBN(0x9d457798, 0x326aad8d), TOBN(0xbdef4954, 0xc396f7e7),
+ TOBN(0x6fb274a2, 0xc253e292), TOBN(0x2800bf0a, 0x1cfe53e7)},
+ {TOBN(0x22426d31, 0x44438fd4), TOBN(0xef233923, 0x5e259f9a),
+ TOBN(0x4188503c, 0x03f66264), TOBN(0x9e5e7f13, 0x7f9fdfab)}},
+ {{TOBN(0x565eb76c, 0x5fcc1aba), TOBN(0xea632548, 0x59b5bff8),
+ TOBN(0x5587c087, 0xaab6d3fa), TOBN(0x92b639ea, 0x6ce39c1b)},
+ {TOBN(0x0706e782, 0x953b135c), TOBN(0x7308912e, 0x425268ef),
+ TOBN(0x599e92c7, 0x090e7469), TOBN(0x83b90f52, 0x9bc35e75)}},
+ {{TOBN(0x4750b3d0, 0x244975b3), TOBN(0xf3a44358, 0x11965d72),
+ TOBN(0x179c6774, 0x9c8dc751), TOBN(0xff18cdfe, 0xd23d9ff0)},
+ {TOBN(0xc4013833, 0x2028e247), TOBN(0x96e280e2, 0xf3bfbc79),
+ TOBN(0xf60417bd, 0xd0880a84), TOBN(0x263c9f3d, 0x2a568151)}},
+ {{TOBN(0x36be15b3, 0x2d2ce811), TOBN(0x846dc0c2, 0xf8291d21),
+ TOBN(0x5cfa0ecb, 0x789fcfdb), TOBN(0x45a0beed, 0xd7535b9a)},
+ {TOBN(0xec8e9f07, 0x96d69af1), TOBN(0x31a7c5b8, 0x599ab6dc),
+ TOBN(0xd36d45ef, 0xf9e2e09f), TOBN(0x3cf49ef1, 0xdcee954b)}},
+ {{TOBN(0x6be34cf3, 0x086cff9b), TOBN(0x88dbd491, 0x39a3360f),
+ TOBN(0x1e96b8cc, 0x0dbfbd1d), TOBN(0xc1e5f7bf, 0xcb7e2552)},
+ {TOBN(0x0547b214, 0x28819d98), TOBN(0xc770dd9c, 0x7aea9dcb),
+ TOBN(0xaef0d4c7, 0x041d68c8), TOBN(0xcc2b9818, 0x13cb9ba8)}},
+ {{TOBN(0x7fc7bc76, 0xfe86c607), TOBN(0x6b7b9337, 0x502a9a95),
+ TOBN(0x1948dc27, 0xd14dab63), TOBN(0x249dd198, 0xdae047be)},
+ {TOBN(0xe8356584, 0xa981a202), TOBN(0x3531dd18, 0x3a893387),
+ TOBN(0x1be11f90, 0xc85c7209), TOBN(0x93d2fe1e, 0xe2a52b5a)}},
+ {{TOBN(0x8225bfe2, 0xec6d6b97), TOBN(0x9cf6d6f4, 0xbd0aa5de),
+ TOBN(0x911459cb, 0x54779f5f), TOBN(0x5649cddb, 0x86aeb1f3)},
+ {TOBN(0x32133579, 0x3f26ce5a), TOBN(0xc289a102, 0x550f431e),
+ TOBN(0x559dcfda, 0x73b84c6f), TOBN(0x84973819, 0xee3ac4d7)}},
+ {{TOBN(0xb51e55e6, 0xf2606a82), TOBN(0xe25f7061, 0x90f2fb57),
+ TOBN(0xacef6c2a, 0xb1a4e37c), TOBN(0x864e359d, 0x5dcf2706)},
+ {TOBN(0x479e6b18, 0x7ce57316), TOBN(0x2cab2500, 0x3a96b23d),
+ TOBN(0xed489862, 0x8ef16df7), TOBN(0x2056538c, 0xef3758b5)}},
+ {{TOBN(0xa7df865e, 0xf15d3101), TOBN(0x80c5533a, 0x61b553d7),
+ TOBN(0x366e1997, 0x4ed14294), TOBN(0x6620741f, 0xb3c0bcd6)},
+ {TOBN(0x21d1d9c4, 0xedc45418), TOBN(0x005b859e, 0xc1cc4a9d),
+ TOBN(0xdf01f630, 0xa1c462f0), TOBN(0x15d06cf3, 0xf26820c7)}},
+ {{TOBN(0x9f7f24ee, 0x3484be47), TOBN(0x2ff33e96, 0x4a0c902f),
+ TOBN(0x00bdf457, 0x5a0bc453), TOBN(0x2378dfaf, 0x1aa238db)},
+ {TOBN(0x272420ec, 0x856720f2), TOBN(0x2ad9d95b, 0x96797291),
+ TOBN(0xd1242cc6, 0x768a1558), TOBN(0x2e287f8b, 0x5cc86aa8)}},
+ {{TOBN(0x796873d0, 0x990cecaa), TOBN(0xade55f81, 0x675d4080),
+ TOBN(0x2645eea3, 0x21f0cd84), TOBN(0x7a1efa0f, 0xb4e17d02)},
+ {TOBN(0xf6858420, 0x037cc061), TOBN(0x682e05f0, 0xd5d43e12),
+ TOBN(0x59c36994, 0x27218710), TOBN(0x85cbba4d, 0x3f7cd2fc)}},
+ {{TOBN(0x726f9729, 0x7a3cd22a), TOBN(0x9f8cd5dc, 0x4a628397),
+ TOBN(0x17b93ab9, 0xc23165ed), TOBN(0xff5f5dbf, 0x122823d4)},
+ {TOBN(0xc1e4e4b5, 0x654a446d), TOBN(0xd1a9496f, 0x677257ba),
+ TOBN(0x6387ba94, 0xde766a56), TOBN(0x23608bc8, 0x521ec74a)}},
+ {{TOBN(0x16a522d7, 0x6688c4d4), TOBN(0x9d6b4282, 0x07373abd),
+ TOBN(0xa62f07ac, 0xb42efaa3), TOBN(0xf73e00f7, 0xe3b90180)},
+ {TOBN(0x36175fec, 0x49421c3e), TOBN(0xc4e44f9b, 0x3dcf2678),
+ TOBN(0x76df436b, 0x7220f09f), TOBN(0x172755fb, 0x3aa8b6cf)}},
+ {{TOBN(0xbab89d57, 0x446139cc), TOBN(0x0a0a6e02, 0x5fe0208f),
+ TOBN(0xcdbb63e2, 0x11e5d399), TOBN(0x33ecaa12, 0xa8977f0b)},
+ {TOBN(0x59598b21, 0xf7c42664), TOBN(0xb3e91b32, 0xab65d08a),
+ TOBN(0x035822ee, 0xf4502526), TOBN(0x1dcf0176, 0x720a82a9)}},
+ {{TOBN(0x50f8598f, 0x3d589e02), TOBN(0xdf0478ff, 0xb1d63d2c),
+ TOBN(0x8b8068bd, 0x1571cd07), TOBN(0x30c3aa4f, 0xd79670cd)},
+ {TOBN(0x25e8fd4b, 0x941ade7f), TOBN(0x3d1debdc, 0x32790011),
+ TOBN(0x65b6dcbd, 0x3a3f9ff0), TOBN(0x282736a4, 0x793de69c)}},
+ {{TOBN(0xef69a0c3, 0xd41d3bd3), TOBN(0xb533b8c9, 0x07a26bde),
+ TOBN(0xe2801d97, 0xdb2edf9f), TOBN(0xdc4a8269, 0xe1877af0)},
+ {TOBN(0x6c1c5851, 0x3d590dbe), TOBN(0x84632f6b, 0xee4e9357),
+ TOBN(0xd36d36b7, 0x79b33374), TOBN(0xb46833e3, 0x9bbca2e6)}},
+ {{TOBN(0x37893913, 0xf7fc0586), TOBN(0x385315f7, 0x66bf4719),
+ TOBN(0x72c56293, 0xb31855dc), TOBN(0xd1416d4e, 0x849061fe)},
+ {TOBN(0xbeb3ab78, 0x51047213), TOBN(0x447f6e61, 0xf040c996),
+ TOBN(0xd06d310d, 0x638b1d0c), TOBN(0xe28a413f, 0xbad1522e)}},
+ {{TOBN(0x685a76cb, 0x82003f86), TOBN(0x610d07f7, 0x0bcdbca3),
+ TOBN(0x6ff66021, 0x9ca4c455), TOBN(0x7df39b87, 0xcea10eec)},
+ {TOBN(0xb9255f96, 0xe22db218), TOBN(0x8cc6d9eb, 0x08a34c44),
+ TOBN(0xcd4ffb86, 0x859f9276), TOBN(0x8fa15eb2, 0x50d07335)}},
+ {{TOBN(0xdf553845, 0xcf2c24b5), TOBN(0x89f66a9f, 0x52f9c3ba),
+ TOBN(0x8f22b5b9, 0xe4a7ceb3), TOBN(0xaffef809, 0x0e134686)},
+ {TOBN(0x3e53e1c6, 0x8eb8fac2), TOBN(0x93c1e4eb, 0x28aec98e),
+ TOBN(0xb6b91ec5, 0x32a43bcb), TOBN(0x2dbfa947, 0xb2d74a51)}},
+ {{TOBN(0xe065d190, 0xca84bad7), TOBN(0xfb13919f, 0xad58e65c),
+ TOBN(0x3c41718b, 0xf1cb6e31), TOBN(0x688969f0, 0x06d05c3f)},
+ {TOBN(0xd4f94ce7, 0x21264d45), TOBN(0xfdfb65e9, 0x7367532b),
+ TOBN(0x5b1be8b1, 0x0945a39d), TOBN(0x229f789c, 0x2b8baf3b)}},
+ {{TOBN(0xd8f41f3e, 0x6f49f15d), TOBN(0x678ce828, 0x907f0792),
+ TOBN(0xc69ace82, 0xfca6e867), TOBN(0x106451ae, 0xd01dcc89)},
+ {TOBN(0x1bb4f7f0, 0x19fc32d2), TOBN(0x64633dfc, 0xb00c52d2),
+ TOBN(0x8f13549a, 0xad9ea445), TOBN(0x99a3bf50, 0xfb323705)}},
+ {{TOBN(0x0c9625a2, 0x534d4dbc), TOBN(0x45b8f1d1, 0xc2a2fea3),
+ TOBN(0x76ec21a1, 0xa530fc1a), TOBN(0x4bac9c2a, 0x9e5bd734)},
+ {TOBN(0x5996d76a, 0x7b4e3587), TOBN(0x0045cdee, 0x1182d9e3),
+ TOBN(0x1aee24b9, 0x1207f13d), TOBN(0x66452e97, 0x97345a41)}},
+ {{TOBN(0x16e5b054, 0x9f950cd0), TOBN(0x9cc72fb1, 0xd7fdd075),
+ TOBN(0x6edd61e7, 0x66249663), TOBN(0xde4caa4d, 0xf043cccb)},
+ {TOBN(0x11b1f57a, 0x55c7ac17), TOBN(0x779cbd44, 0x1a85e24d),
+ TOBN(0x78030f86, 0xe46081e7), TOBN(0xfd4a6032, 0x8e20f643)}},
+ {{TOBN(0xcc7a6488, 0x0a750c0f), TOBN(0x39bacfe3, 0x4e548e83),
+ TOBN(0x3d418c76, 0x0c110f05), TOBN(0x3e4daa4c, 0xb1f11588)},
+ {TOBN(0x2733e7b5, 0x5ffc69ff), TOBN(0x46f147bc, 0x92053127),
+ TOBN(0x885b2434, 0xd722df94), TOBN(0x6a444f65, 0xe6fc6b7c)}}},
+ {{{TOBN(0x7a1a465a, 0xc3f16ea8), TOBN(0x115a461d, 0xb2f1d11c),
+ TOBN(0x4767dd95, 0x6c68a172), TOBN(0x3392f2eb, 0xd13a4698)},
+ {TOBN(0xc7a99ccd, 0xe526cdc7), TOBN(0x8e537fdc, 0x22292b81),
+ TOBN(0x76d8cf69, 0xa6d39198), TOBN(0xffc5ff43, 0x2446852d)}},
+ {{TOBN(0x97b14f7e, 0xa90567e6), TOBN(0x513257b7, 0xb6ae5cb7),
+ TOBN(0x85454a3c, 0x9f10903d), TOBN(0xd8d2c9ad, 0x69bc3724)},
+ {TOBN(0x38da9324, 0x6b29cb44), TOBN(0xb540a21d, 0x77c8cbac),
+ TOBN(0x9bbfe435, 0x01918e42), TOBN(0xfffa707a, 0x56c3614e)}},
+ {{TOBN(0x0ce4e3f1, 0xd4e353b7), TOBN(0x062d8a14, 0xef46b0a0),
+ TOBN(0x6408d5ab, 0x574b73fd), TOBN(0xbc41d1c9, 0xd3273ffd)},
+ {TOBN(0x3538e1e7, 0x6be77800), TOBN(0x71fe8b37, 0xc5655031),
+ TOBN(0x1cd91621, 0x6b9b331a), TOBN(0xad825d0b, 0xbb388f73)}},
+ {{TOBN(0x56c2e05b, 0x1cb76219), TOBN(0x0ec0bf91, 0x71567e7e),
+ TOBN(0xe7076f86, 0x61c4c910), TOBN(0xd67b085b, 0xbabc04d9)},
+ {TOBN(0x9fb90459, 0x5e93a96a), TOBN(0x7526c1ea, 0xfbdc249a),
+ TOBN(0x0d44d367, 0xecdd0bb7), TOBN(0x95399917, 0x9dc0d695)}},
+ {{TOBN(0x61360ee9, 0x9e240d18), TOBN(0x057cdcac, 0xb4b94466),
+ TOBN(0xe7667cd1, 0x2fe5325c), TOBN(0x1fa297b5, 0x21974e3b)},
+ {TOBN(0xfa4081e7, 0xdb083d76), TOBN(0x31993be6, 0xf206bd15),
+ TOBN(0x8949269b, 0x14c19f8c), TOBN(0x21468d72, 0xa9d92357)}},
+ {{TOBN(0x2ccbc583, 0xa4c506ec), TOBN(0x957ed188, 0xd1acfe97),
+ TOBN(0x8baed833, 0x12f1aea2), TOBN(0xef2a6cb4, 0x8325362d)},
+ {TOBN(0x130dde42, 0x8e195c43), TOBN(0xc842025a, 0x0e6050c6),
+ TOBN(0x2da972a7, 0x08686a5d), TOBN(0xb52999a1, 0xe508b4a8)}},
+ {{TOBN(0xd9f090b9, 0x10a5a8bd), TOBN(0xca91d249, 0x096864da),
+ TOBN(0x8e6a93be, 0x3f67dbc1), TOBN(0xacae6fba, 0xf5f4764c)},
+ {TOBN(0x1563c6e0, 0xd21411a0), TOBN(0x28fa787f, 0xda0a4ad8),
+ TOBN(0xd524491c, 0x908c8030), TOBN(0x1257ba0e, 0x4c795f07)}},
+ {{TOBN(0x83f49167, 0xceca9754), TOBN(0x426d2cf6, 0x4b7939a0),
+ TOBN(0x2555e355, 0x723fd0bf), TOBN(0xa96e6d06, 0xc4f144e2)},
+ {TOBN(0x4768a8dd, 0x87880e61), TOBN(0x15543815, 0xe508e4d5),
+ TOBN(0x09d7e772, 0xb1b65e15), TOBN(0x63439dd6, 0xac302fa0)}},
+ {{TOBN(0xb93f802f, 0xc14e35c2), TOBN(0x71735b7c, 0x4341333c),
+ TOBN(0x03a25104, 0x16d4f362), TOBN(0x3f4d069b, 0xbf433c8e)},
+ {TOBN(0x0d83ae01, 0xf78f5a7c), TOBN(0x50a8ffbe, 0x7c4eed07),
+ TOBN(0xc74f8906, 0x76e10f83), TOBN(0x7d080966, 0x9ddaf8e1)}},
+ {{TOBN(0xb11df8e1, 0x698e04cc), TOBN(0x877be203, 0x169005c8),
+ TOBN(0x32749e8c, 0x4f3c6179), TOBN(0x2dbc9d0a, 0x7853fc05)},
+ {TOBN(0x187d4f93, 0x9454d937), TOBN(0xe682ce9d, 0xb4800e1b),
+ TOBN(0xa9129ad8, 0x165e68e8), TOBN(0x0fe29735, 0xbe7f785b)}},
+ {{TOBN(0x5303f40c, 0x5b9e02b7), TOBN(0xa37c9692, 0x35ee04e8),
+ TOBN(0x5f46cc20, 0x34d6632b), TOBN(0x55ef72b2, 0x96ac545b)},
+ {TOBN(0xabec5c1f, 0x7b91b062), TOBN(0x0a79e1c7, 0xbb33e821),
+ TOBN(0xbb04b428, 0x3a9f4117), TOBN(0x0de1f28f, 0xfd2a475a)}},
+ {{TOBN(0x31019ccf, 0x3a4434b4), TOBN(0xa3458111, 0x1a7954dc),
+ TOBN(0xa9dac80d, 0xe34972a7), TOBN(0xb043d054, 0x74f6b8dd)},
+ {TOBN(0x021c319e, 0x11137b1a), TOBN(0x00a754ce, 0xed5cc03f),
+ TOBN(0x0aa2c794, 0xcbea5ad4), TOBN(0x093e67f4, 0x70c015b6)}},
+ {{TOBN(0x72cdfee9, 0xc97e3f6b), TOBN(0xc10bcab4, 0xb6da7461),
+ TOBN(0x3b02d2fc, 0xb59806b9), TOBN(0x85185e89, 0xa1de6f47)},
+ {TOBN(0x39e6931f, 0x0eb6c4d4), TOBN(0x4d4440bd, 0xd4fa5b04),
+ TOBN(0x5418786e, 0x34be7eb8), TOBN(0x6380e521, 0x9d7259bc)}},
+ {{TOBN(0x20ac0351, 0xd598d710), TOBN(0x272c4166, 0xcb3a4da4),
+ TOBN(0xdb82fe1a, 0xca71de1f), TOBN(0x746e79f2, 0xd8f54b0f)},
+ {TOBN(0x6e7fc736, 0x4b573e9b), TOBN(0x75d03f46, 0xfd4b5040),
+ TOBN(0x5c1cc36d, 0x0b98d87b), TOBN(0x513ba3f1, 0x1f472da1)}},
+ {{TOBN(0x79d0af26, 0xabb177dd), TOBN(0xf82ab568, 0x7891d564),
+ TOBN(0x2b6768a9, 0x72232173), TOBN(0xefbb3bb0, 0x8c1f6619)},
+ {TOBN(0xb29c11db, 0xa6d18358), TOBN(0x519e2797, 0xb0916d3a),
+ TOBN(0xd4dc18f0, 0x9188e290), TOBN(0x648e86e3, 0x98b0ca7f)}},
+ {{TOBN(0x859d3145, 0x983c38b5), TOBN(0xb14f176c, 0x637abc8b),
+ TOBN(0x2793fb9d, 0xcaff7be6), TOBN(0xebe5a55f, 0x35a66a5a)},
+ {TOBN(0x7cec1dcd, 0x9f87dc59), TOBN(0x7c595cd3, 0xfbdbf560),
+ TOBN(0x5b543b22, 0x26eb3257), TOBN(0x69080646, 0xc4c935fd)}},
+ {{TOBN(0x7f2e4403, 0x81e9ede3), TOBN(0x243c3894, 0xcaf6df0a),
+ TOBN(0x7c605bb1, 0x1c073b11), TOBN(0xcd06a541, 0xba6a4a62)},
+ {TOBN(0x29168949, 0x49d4e2e5), TOBN(0x33649d07, 0x4af66880),
+ TOBN(0xbfc0c885, 0xe9a85035), TOBN(0xb4e52113, 0xfc410f4b)}},
+ {{TOBN(0xdca3b706, 0x78a6513b), TOBN(0x92ea4a2a, 0x9edb1943),
+ TOBN(0x02642216, 0xdb6e2dd8), TOBN(0x9b45d0b4, 0x9fd57894)},
+ {TOBN(0x114e70db, 0xc69d11ae), TOBN(0x1477dd19, 0x4c57595f),
+ TOBN(0xbc2208b4, 0xec77c272), TOBN(0x95c5b4d7, 0xdb68f59c)}},
+ {{TOBN(0xb8c4fc63, 0x42e532b7), TOBN(0x386ba422, 0x9ae35290),
+ TOBN(0xfb5dda42, 0xd201ecbc), TOBN(0x2353dc8b, 0xa0e38fd6)},
+ {TOBN(0x9a0b85ea, 0x68f7e978), TOBN(0x96ec5682, 0x2ad6d11f),
+ TOBN(0x5e279d6c, 0xe5f6886d), TOBN(0xd3fe03cd, 0x3cb1914d)}},
+ {{TOBN(0xfe541fa4, 0x7ea67c77), TOBN(0x952bd2af, 0xe3ea810c),
+ TOBN(0x791fef56, 0x8d01d374), TOBN(0xa3a1c621, 0x0f11336e)},
+ {TOBN(0x5ad0d5a9, 0xc7ec6d79), TOBN(0xff7038af, 0x3225c342),
+ TOBN(0x003c6689, 0xbc69601b), TOBN(0x25059bc7, 0x45e8747d)}},
+ {{TOBN(0xfa4965b2, 0xf2086fbf), TOBN(0xf6840ea6, 0x86916078),
+ TOBN(0xd7ac7620, 0x70081d6c), TOBN(0xe600da31, 0xb5328645)},
+ {TOBN(0x01916f63, 0x529b8a80), TOBN(0xe80e4858, 0x2d7d6f3e),
+ TOBN(0x29eb0fe8, 0xd664ca7c), TOBN(0xf017637b, 0xe7b43b0c)}},
+ {{TOBN(0x9a75c806, 0x76cb2566), TOBN(0x8f76acb1, 0xb24892d9),
+ TOBN(0x7ae7b9cc, 0x1f08fe45), TOBN(0x19ef7329, 0x6a4907d8)},
+ {TOBN(0x2db4ab71, 0x5f228bf0), TOBN(0xf3cdea39, 0x817032d7),
+ TOBN(0x0b1f482e, 0xdcabe3c0), TOBN(0x3baf76b4, 0xbb86325c)}},
+ {{TOBN(0xd49065e0, 0x10089465), TOBN(0x3bab5d29, 0x8e77c596),
+ TOBN(0x7636c3a6, 0x193dbd95), TOBN(0xdef5d294, 0xb246e499)},
+ {TOBN(0xb22c58b9, 0x286b2475), TOBN(0xa0b93939, 0xcd80862b),
+ TOBN(0x3002c83a, 0xf0992388), TOBN(0x6de01f9b, 0xeacbe14c)}},
+ {{TOBN(0x6aac688e, 0xadd70482), TOBN(0x708de92a, 0x7b4a4e8a),
+ TOBN(0x75b6dd73, 0x758a6eef), TOBN(0xea4bf352, 0x725b3c43)},
+ {TOBN(0x10041f2c, 0x87912868), TOBN(0xb1b1be95, 0xef09297a),
+ TOBN(0x19ae23c5, 0xa9f3860a), TOBN(0xc4f0f839, 0x515dcf4b)}},
+ {{TOBN(0x3c7ecca3, 0x97f6306a), TOBN(0x744c44ae, 0x68a3a4b0),
+ TOBN(0x69cd13a0, 0xb3a1d8a2), TOBN(0x7cad0a1e, 0x5256b578)},
+ {TOBN(0xea653fcd, 0x33791d9e), TOBN(0x9cc2a05d, 0x74b2e05f),
+ TOBN(0x73b391dc, 0xfd7affa2), TOBN(0xddb7091e, 0xb6b05442)}},
+ {{TOBN(0xc71e27bf, 0x8538a5c6), TOBN(0x195c63dd, 0x89abff17),
+ TOBN(0xfd315285, 0x1b71e3da), TOBN(0x9cbdfda7, 0xfa680fa0)},
+ {TOBN(0x9db876ca, 0x849d7eab), TOBN(0xebe2764b, 0x3c273271),
+ TOBN(0x663357e3, 0xf208dcea), TOBN(0x8c5bd833, 0x565b1b70)}},
+ {{TOBN(0xccc3b4f5, 0x9837fc0d), TOBN(0x9b641ba8, 0xa79cf00f),
+ TOBN(0x7428243d, 0xdfdf3990), TOBN(0x83a594c4, 0x020786b1)},
+ {TOBN(0xb712451a, 0x526c4502), TOBN(0x9d39438e, 0x6adb3f93),
+ TOBN(0xfdb261e3, 0xe9ff0ccd), TOBN(0x80344e3c, 0xe07af4c3)}},
+ {{TOBN(0x75900d7c, 0x2fa4f126), TOBN(0x08a3b865, 0x5c99a232),
+ TOBN(0x2478b6bf, 0xdb25e0c3), TOBN(0x482cc2c2, 0x71db2edf)},
+ {TOBN(0x37df7e64, 0x5f321bb8), TOBN(0x8a93821b, 0x9a8005b4),
+ TOBN(0x3fa2f10c, 0xcc8c1958), TOBN(0x0d332218, 0x2c269d0a)}},
+ {{TOBN(0x20ab8119, 0xe246b0e6), TOBN(0xb39781e4, 0xd349fd17),
+ TOBN(0xd293231e, 0xb31aa100), TOBN(0x4b779c97, 0xbb032168)},
+ {TOBN(0x4b3f19e1, 0xc8470500), TOBN(0x45b7efe9, 0x0c4c869d),
+ TOBN(0xdb84f38a, 0xa1a6bbcc), TOBN(0x3b59cb15, 0xb2fddbc1)}},
+ {{TOBN(0xba5514df, 0x3fd165e8), TOBN(0x499fd6a9, 0x061f8811),
+ TOBN(0x72cd1fe0, 0xbfef9f00), TOBN(0x120a4bb9, 0x79ad7e8a)},
+ {TOBN(0xf2ffd095, 0x5f4a5ac5), TOBN(0xcfd174f1, 0x95a7a2f0),
+ TOBN(0xd42301ba, 0x9d17baf1), TOBN(0xd2fa487a, 0x77f22089)}},
+ {{TOBN(0x9cb09efe, 0xb1dc77e1), TOBN(0xe9566939, 0x21c99682),
+ TOBN(0x8c546901, 0x6c6067bb), TOBN(0xfd378574, 0x61c24456)},
+ {TOBN(0x2b6a6cbe, 0x81796b33), TOBN(0x62d550f6, 0x58e87f8b),
+ TOBN(0x1b763e1c, 0x7f1b01b4), TOBN(0x4b93cfea, 0x1b1b5e12)}},
+ {{TOBN(0xb9345238, 0x1d531696), TOBN(0x57201c00, 0x88cdde69),
+ TOBN(0xdde92251, 0x9a86afc7), TOBN(0xe3043895, 0xbd35cea8)},
+ {TOBN(0x7608c1e1, 0x8555970d), TOBN(0x8267dfa9, 0x2535935e),
+ TOBN(0xd4c60a57, 0x322ea38b), TOBN(0xe0bf7977, 0x804ef8b5)}},
+ {{TOBN(0x1a0dab28, 0xc06fece4), TOBN(0xd405991e, 0x94e7b49d),
+ TOBN(0xc542b6d2, 0x706dab28), TOBN(0xcb228da3, 0xa91618fb)},
+ {TOBN(0x224e4164, 0x107d1cea), TOBN(0xeb9fdab3, 0xd0f5d8f1),
+ TOBN(0xc02ba386, 0x0d6e41cd), TOBN(0x676a72c5, 0x9b1f7146)}},
+ {{TOBN(0xffd6dd98, 0x4d6cb00b), TOBN(0xcef9c5ca, 0xde2e8d7c),
+ TOBN(0xa1bbf5d7, 0x641c7936), TOBN(0x1b95b230, 0xee8f772e)},
+ {TOBN(0xf765a92e, 0xe8ac25b1), TOBN(0xceb04cfc, 0x3a18b7c6),
+ TOBN(0x27944cef, 0x0acc8966), TOBN(0xcbb3c957, 0x434c1004)}},
+ {{TOBN(0x9c9971a1, 0xa43ff93c), TOBN(0x5bc2db17, 0xa1e358a9),
+ TOBN(0x45b4862e, 0xa8d9bc82), TOBN(0x70ebfbfb, 0x2201e052)},
+ {TOBN(0xafdf64c7, 0x92871591), TOBN(0xea5bcae6, 0xb42d0219),
+ TOBN(0xde536c55, 0x2ad8f03c), TOBN(0xcd6c3f4d, 0xa76aa33c)}},
+ {{TOBN(0xbeb5f623, 0x0bca6de3), TOBN(0xdd20dd99, 0xb1e706fd),
+ TOBN(0x90b3ff9d, 0xac9059d4), TOBN(0x2d7b2902, 0x7ccccc4e)},
+ {TOBN(0x8a090a59, 0xce98840f), TOBN(0xa5d947e0, 0x8410680a),
+ TOBN(0x49ae346a, 0x923379a5), TOBN(0x7dbc84f9, 0xb28a3156)}},
+ {{TOBN(0xfd40d916, 0x54a1aff2), TOBN(0xabf318ba, 0x3a78fb9b),
+ TOBN(0x50152ed8, 0x3029f95e), TOBN(0x9fc1dd77, 0xc58ad7fa)},
+ {TOBN(0x5fa57915, 0x13595c17), TOBN(0xb9504668, 0x8f62b3a9),
+ TOBN(0x907b5b24, 0xff3055b0), TOBN(0x2e995e35, 0x9a84f125)}},
+ {{TOBN(0x87dacf69, 0x7e9bbcfb), TOBN(0x95d0c1d6, 0xe86d96e3),
+ TOBN(0x65726e3c, 0x2d95a75c), TOBN(0x2c3c9001, 0xacd27f21)},
+ {TOBN(0x1deab561, 0x6c973f57), TOBN(0x108b7e2c, 0xa5221643),
+ TOBN(0x5fee9859, 0xc4ef79d4), TOBN(0xbd62b88a, 0x40d4b8c6)}},
+ {{TOBN(0xb4dd29c4, 0x197c75d6), TOBN(0x266a6df2, 0xb7076feb),
+ TOBN(0x9512d0ea, 0x4bf2df11), TOBN(0x1320c24f, 0x6b0cc9ec)},
+ {TOBN(0x6bb1e0e1, 0x01a59596), TOBN(0x8317c5bb, 0xeff9aaac),
+ TOBN(0x65bb405e, 0x385aa6c9), TOBN(0x613439c1, 0x8f07988f)}},
+ {{TOBN(0xd730049f, 0x16a66e91), TOBN(0xe97f2820, 0xfa1b0e0d),
+ TOBN(0x4131e003, 0x304c28ea), TOBN(0x820ab732, 0x526bac62)},
+ {TOBN(0xb2ac9ef9, 0x28714423), TOBN(0x54ecfffa, 0xadb10cb2),
+ TOBN(0x8781476e, 0xf886a4cc), TOBN(0x4b2c87b5, 0xdb2f8d49)}},
+ {{TOBN(0xe857cd20, 0x0a44295d), TOBN(0x707d7d21, 0x58c6b044),
+ TOBN(0xae8521f9, 0xf596757c), TOBN(0x87448f03, 0x67b2b714)},
+ {TOBN(0x13a9bc45, 0x5ebcd58d), TOBN(0x79bcced9, 0x9122d3c1),
+ TOBN(0x3c644247, 0x9e076642), TOBN(0x0cf22778, 0x2df4767d)}},
+ {{TOBN(0x5e61aee4, 0x71d444b6), TOBN(0x211236bf, 0xc5084a1d),
+ TOBN(0x7e15bc9a, 0x4fd3eaf6), TOBN(0x68df2c34, 0xab622bf5)},
+ {TOBN(0x9e674f0f, 0x59bf4f36), TOBN(0xf883669b, 0xd7f34d73),
+ TOBN(0xc48ac1b8, 0x31497b1d), TOBN(0x323b925d, 0x5106703b)}},
+ {{TOBN(0x22156f42, 0x74082008), TOBN(0xeffc521a, 0xc8482bcb),
+ TOBN(0x5c6831bf, 0x12173479), TOBN(0xcaa2528f, 0xc4739490)},
+ {TOBN(0x84d2102a, 0x8f1b3c4d), TOBN(0xcf64dfc1, 0x2d9bec0d),
+ TOBN(0x433febad, 0x78a546ef), TOBN(0x1f621ec3, 0x7b73cef1)}},
+ {{TOBN(0x6aecd627, 0x37338615), TOBN(0x162082ab, 0x01d8edf6),
+ TOBN(0x833a8119, 0x19e86b66), TOBN(0x6023a251, 0xd299b5db)},
+ {TOBN(0xf5bb0c3a, 0xbbf04b89), TOBN(0x6735eb69, 0xae749a44),
+ TOBN(0xd0e058c5, 0x4713de3b), TOBN(0xfdf2593e, 0x2c3d4ccd)}},
+ {{TOBN(0x1b8f414e, 0xfdd23667), TOBN(0xdd52aaca, 0xfa2015ee),
+ TOBN(0x3e31b517, 0xbd9625ff), TOBN(0x5ec9322d, 0x8db5918c)},
+ {TOBN(0xbc73ac85, 0xa96f5294), TOBN(0x82aa5bf3, 0x61a0666a),
+ TOBN(0x49755810, 0xbf08ac42), TOBN(0xd21cdfd5, 0x891cedfc)}},
+ {{TOBN(0x918cb57b, 0x67f8be10), TOBN(0x365d1a7c, 0x56ffa726),
+ TOBN(0x2435c504, 0x6532de93), TOBN(0xc0fc5e10, 0x2674cd02)},
+ {TOBN(0x6e51fcf8, 0x9cbbb142), TOBN(0x1d436e5a, 0xafc50692),
+ TOBN(0x766bffff, 0x3fbcae22), TOBN(0x3148c2fd, 0xfd55d3b8)}},
+ {{TOBN(0x52c7fdc9, 0x233222fa), TOBN(0x89ff1092, 0xe419fb6b),
+ TOBN(0x3cd6db99, 0x25254977), TOBN(0x2e85a161, 0x1cf12ca7)},
+ {TOBN(0xadd2547c, 0xdc810bc9), TOBN(0xea3f458f, 0x9d257c22),
+ TOBN(0x642c1fbe, 0x27d6b19b), TOBN(0xed07e6b5, 0x140481a6)}},
+ {{TOBN(0x6ada1d42, 0x86d2e0f8), TOBN(0xe5920122, 0x0e8a9fd5),
+ TOBN(0x02c936af, 0x708c1b49), TOBN(0x60f30fee, 0x2b4bfaff)},
+ {TOBN(0x6637ad06, 0x858e6a61), TOBN(0xce4c7767, 0x3fd374d0),
+ TOBN(0x39d54b2d, 0x7188defb), TOBN(0xa8c9d250, 0xf56a6b66)}},
+ {{TOBN(0x58fc0f5e, 0xb24fe1dc), TOBN(0x9eaf9dee, 0x6b73f24c),
+ TOBN(0xa90d588b, 0x33650705), TOBN(0xde5b62c5, 0xaf2ec729)},
+ {TOBN(0x5c72cfae, 0xd3c2b36e), TOBN(0x868c19d5, 0x034435da),
+ TOBN(0x88605f93, 0xe17ee145), TOBN(0xaa60c4ee, 0x77a5d5b1)}},
+ {{TOBN(0xbcf5bfd2, 0x3b60c472), TOBN(0xaf4ef13c, 0xeb1d3049),
+ TOBN(0x373f44fc, 0xe13895c9), TOBN(0xf29b382f, 0x0cbc9822)},
+ {TOBN(0x1bfcb853, 0x73efaef6), TOBN(0xcf56ac9c, 0xa8c96f40),
+ TOBN(0xd7adf109, 0x7a191e24), TOBN(0x98035f44, 0xbf8a8dc2)}},
+ {{TOBN(0xf40a71b9, 0x1e750c84), TOBN(0xc57f7b0c, 0x5dc6c469),
+ TOBN(0x49a0e79c, 0x6fbc19c1), TOBN(0x6b0f5889, 0xa48ebdb8)},
+ {TOBN(0x5d3fd084, 0xa07c4e9f), TOBN(0xc3830111, 0xab27de14),
+ TOBN(0x0e4929fe, 0x33e08dcc), TOBN(0xf4a5ad24, 0x40bb73a3)}},
+ {{TOBN(0xde86c2bf, 0x490f97ca), TOBN(0x288f09c6, 0x67a1ce18),
+ TOBN(0x364bb886, 0x1844478d), TOBN(0x7840fa42, 0xceedb040)},
+ {TOBN(0x1269fdd2, 0x5a631b37), TOBN(0x94761f1e, 0xa47c8b7d),
+ TOBN(0xfc0c2e17, 0x481c6266), TOBN(0x85e16ea2, 0x3daa5fa7)}},
+ {{TOBN(0xccd86033, 0x92491048), TOBN(0x0c2f6963, 0xf4d402d7),
+ TOBN(0x6336f7df, 0xdf6a865c), TOBN(0x0a2a463c, 0xb5c02a87)},
+ {TOBN(0xb0e29be7, 0xbf2f12ee), TOBN(0xf0a22002, 0x66bad988),
+ TOBN(0x27f87e03, 0x9123c1d7), TOBN(0x21669c55, 0x328a8c98)}},
+ {{TOBN(0x186b9803, 0x92f14529), TOBN(0xd3d056cc, 0x63954df3),
+ TOBN(0x2f03fd58, 0x175a46f6), TOBN(0x63e34ebe, 0x11558558)},
+ {TOBN(0xe13fedee, 0x5b80cfa5), TOBN(0xe872a120, 0xd401dbd1),
+ TOBN(0x52657616, 0xe8a9d667), TOBN(0xbc8da4b6, 0xe08d6693)}},
+ {{TOBN(0x370fb9bb, 0x1b703e75), TOBN(0x6773b186, 0xd4338363),
+ TOBN(0x18dad378, 0xecef7bff), TOBN(0xaac787ed, 0x995677da)},
+ {TOBN(0x4801ea8b, 0x0437164b), TOBN(0xf430ad20, 0x73fe795e),
+ TOBN(0xb164154d, 0x8ee5eb73), TOBN(0x0884ecd8, 0x108f7c0e)}},
+ {{TOBN(0x0e6ec096, 0x5f520698), TOBN(0x640631fe, 0x44f7b8d9),
+ TOBN(0x92fd34fc, 0xa35a68b9), TOBN(0x9c5a4b66, 0x4d40cf4e)},
+ {TOBN(0x949454bf, 0x80b6783d), TOBN(0x80e701fe, 0x3a320a10),
+ TOBN(0x8d1a564a, 0x1a0a39b2), TOBN(0x1436d53d, 0x320587db)}},
+ {{TOBN(0xf5096e6d, 0x6556c362), TOBN(0xbc23a3c0, 0xe2455d7e),
+ TOBN(0x3a7aee54, 0x807230f9), TOBN(0x9ba1cfa6, 0x22ae82fd)},
+ {TOBN(0x833a057a, 0x99c5d706), TOBN(0x8be85f4b, 0x842315c9),
+ TOBN(0xd083179a, 0x66a72f12), TOBN(0x2fc77d5d, 0xcdcc73cd)}},
+ {{TOBN(0x22b88a80, 0x5616ee30), TOBN(0xfb09548f, 0xe7ab1083),
+ TOBN(0x8ad6ab0d, 0x511270cd), TOBN(0x61f6c57a, 0x6924d9ab)},
+ {TOBN(0xa0f7bf72, 0x90aecb08), TOBN(0x849f87c9, 0x0df784a4),
+ TOBN(0x27c79c15, 0xcfaf1d03), TOBN(0xbbf9f675, 0xc463face)}},
+ {{TOBN(0x91502c65, 0x765ba543), TOBN(0x18ce3cac, 0x42ea60dd),
+ TOBN(0xe5cee6ac, 0x6e43ecb3), TOBN(0x63e4e910, 0x68f2aeeb)},
+ {TOBN(0x26234fa3, 0xc85932ee), TOBN(0x96883e8b, 0x4c90c44d),
+ TOBN(0x29b9e738, 0xa18a50f6), TOBN(0xbfc62b2a, 0x3f0420df)}},
+ {{TOBN(0xd22a7d90, 0x6d3e1fa9), TOBN(0x17115618, 0xfe05b8a3),
+ TOBN(0x2a0c9926, 0xbb2b9c01), TOBN(0xc739fcc6, 0xe07e76a2)},
+ {TOBN(0x540e9157, 0x165e439a), TOBN(0x06353a62, 0x6a9063d8),
+ TOBN(0x84d95594, 0x61e927a3), TOBN(0x013b9b26, 0xe2e0be7f)}},
+ {{TOBN(0x4feaec3b, 0x973497f1), TOBN(0x15c0f94e, 0x093ebc2d),
+ TOBN(0x6af5f227, 0x33af0583), TOBN(0x0c2af206, 0xc61f3340)},
+ {TOBN(0xd25dbdf1, 0x4457397c), TOBN(0x2e8ed017, 0xcabcbae0),
+ TOBN(0xe3010938, 0xc2815306), TOBN(0xbaa99337, 0xe8c6cd68)}},
+ {{TOBN(0x08513182, 0x3b0ec7de), TOBN(0x1e1b822b, 0x58df05df),
+ TOBN(0x5c14842f, 0xa5c3b683), TOBN(0x98fe977e, 0x3eba34ce)},
+ {TOBN(0xfd2316c2, 0x0d5e8873), TOBN(0xe48d839a, 0xbd0d427d),
+ TOBN(0x495b2218, 0x623fc961), TOBN(0x24ee56e7, 0xb46fba5e)}},
+ {{TOBN(0x9184a55b, 0x91e4de58), TOBN(0xa7488ca5, 0xdfdea288),
+ TOBN(0xa723862e, 0xa8dcc943), TOBN(0x92d762b2, 0x849dc0fc)},
+ {TOBN(0x3c444a12, 0x091ff4a9), TOBN(0x581113fa, 0x0cada274),
+ TOBN(0xb9de0a45, 0x30d8eae2), TOBN(0x5e0fcd85, 0xdf6b41ea)}},
+ {{TOBN(0x6233ea68, 0xc094dbb5), TOBN(0xb77d062e, 0xd968d410),
+ TOBN(0x3e719bbc, 0x58b3002d), TOBN(0x68e7dd3d, 0x3dc49d58)},
+ {TOBN(0x8d825740, 0x013a5e58), TOBN(0x21311747, 0x3c9e3c1b),
+ TOBN(0x0cb0a2a7, 0x7c99b6ab), TOBN(0x5c48a3b3, 0xc2f888f2)}}},
+ {{{TOBN(0xc7913e91, 0x991724f3), TOBN(0x5eda799c, 0x39cbd686),
+ TOBN(0xddb595c7, 0x63d4fc1e), TOBN(0x6b63b80b, 0xac4fed54)},
+ {TOBN(0x6ea0fc69, 0x7e5fb516), TOBN(0x737708ba, 0xd0f1c964),
+ TOBN(0x9628745f, 0x11a92ca5), TOBN(0x61f37958, 0x9a86967a)}},
+ {{TOBN(0x9af39b2c, 0xaa665072), TOBN(0x78322fa4, 0xefd324ef),
+ TOBN(0x3d153394, 0xc327bd31), TOBN(0x81d5f271, 0x3129dab0)},
+ {TOBN(0xc72e0c42, 0xf48027f5), TOBN(0xaa40cdbc, 0x8536e717),
+ TOBN(0xf45a657a, 0x2d369d0f), TOBN(0xb03bbfc4, 0xea7f74e6)}},
+ {{TOBN(0x46a8c418, 0x0d738ded), TOBN(0x6f1a5bb0, 0xe0de5729),
+ TOBN(0xf10230b9, 0x8ba81675), TOBN(0x32c6f30c, 0x112b33d4)},
+ {TOBN(0x7559129d, 0xd8fffb62), TOBN(0x6a281b47, 0xb459bf05),
+ TOBN(0x77c1bd3a, 0xfa3b6776), TOBN(0x0709b380, 0x7829973a)}},
+ {{TOBN(0x8c26b232, 0xa3326505), TOBN(0x38d69272, 0xee1d41bf),
+ TOBN(0x0459453e, 0xffe32afa), TOBN(0xce8143ad, 0x7cb3ea87)},
+ {TOBN(0x932ec1fa, 0x7e6ab666), TOBN(0x6cd2d230, 0x22286264),
+ TOBN(0x459a46fe, 0x6736f8ed), TOBN(0x50bf0d00, 0x9eca85bb)}},
+ {{TOBN(0x0b825852, 0x877a21ec), TOBN(0x300414a7, 0x0f537a94),
+ TOBN(0x3f1cba40, 0x21a9a6a2), TOBN(0x50824eee, 0x76943c00)},
+ {TOBN(0xa0dbfcec, 0xf83cba5d), TOBN(0xf9538148, 0x93b4f3c0),
+ TOBN(0x61744162, 0x48f24dd7), TOBN(0x5322d64d, 0xe4fb09dd)}},
+ {{TOBN(0x57447384, 0x3d9325f3), TOBN(0xa9bef2d0, 0xf371cb84),
+ TOBN(0x77d2188b, 0xa61e36c5), TOBN(0xbbd6a7d7, 0xc602df72)},
+ {TOBN(0xba3aa902, 0x8f61bc0b), TOBN(0xf49085ed, 0x6ed0b6a1),
+ TOBN(0x8bc625d6, 0xae6e8298), TOBN(0x832b0b1d, 0xa2e9c01d)}},
+ {{TOBN(0xa337c447, 0xf1f0ced1), TOBN(0x800cc793, 0x9492dd2b),
+ TOBN(0x4b93151d, 0xbea08efa), TOBN(0x820cf3f8, 0xde0a741e)},
+ {TOBN(0xff1982dc, 0x1c0f7d13), TOBN(0xef921960, 0x84dde6ca),
+ TOBN(0x1ad7d972, 0x45f96ee3), TOBN(0x319c8dbe, 0x29dea0c7)}},
+ {{TOBN(0xd3ea3871, 0x7b82b99b), TOBN(0x75922d4d, 0x470eb624),
+ TOBN(0x8f66ec54, 0x3b95d466), TOBN(0x66e673cc, 0xbee1e346)},
+ {TOBN(0x6afe67c4, 0xb5f2b89a), TOBN(0x3de9c1e6, 0x290e5cd3),
+ TOBN(0x8c278bb6, 0x310a2ada), TOBN(0x420fa384, 0x0bdb323b)}},
+ {{TOBN(0x0ae1d63b, 0x0eb919b0), TOBN(0xd74ee51d, 0xa74b9620),
+ TOBN(0x395458d0, 0xa674290c), TOBN(0x324c930f, 0x4620a510)},
+ {TOBN(0x2d1f4d19, 0xfbac27d4), TOBN(0x4086e8ca, 0x9bedeeac),
+ TOBN(0x0cdd211b, 0x9b679ab8), TOBN(0x5970167d, 0x7090fec4)}},
+ {{TOBN(0x3420f2c9, 0xfaf1fc63), TOBN(0x616d333a, 0x328c8bb4),
+ TOBN(0x7d65364c, 0x57f1fe4a), TOBN(0x9343e877, 0x55e5c73a)},
+ {TOBN(0x5795176b, 0xe970e78c), TOBN(0xa36ccebf, 0x60533627),
+ TOBN(0xfc7c7380, 0x09cdfc1b), TOBN(0xb39a2afe, 0xb3fec326)}},
+ {{TOBN(0xb7ff1ba1, 0x6224408a), TOBN(0xcc856e92, 0x247cfc5e),
+ TOBN(0x01f102e7, 0xc18bc493), TOBN(0x4613ab74, 0x2091c727)},
+ {TOBN(0xaa25e89c, 0xc420bf2b), TOBN(0x00a53176, 0x90337ec2),
+ TOBN(0xd2be9f43, 0x7d025fc7), TOBN(0x3316fb85, 0x6e6fe3dc)}},
+ {{TOBN(0x27520af5, 0x9ac50814), TOBN(0xfdf95e78, 0x9a8e4223),
+ TOBN(0xb7e7df2a, 0x56bec5a0), TOBN(0xf7022f7d, 0xdf159e5d)},
+ {TOBN(0x93eeeab1, 0xcac1fe8f), TOBN(0x8040188c, 0x37451168),
+ TOBN(0x7ee8aa8a, 0xd967dce6), TOBN(0xfa0e79e7, 0x3abc9299)}},
+ {{TOBN(0x67332cfc, 0x2064cfd1), TOBN(0x339c31de, 0xb0651934),
+ TOBN(0x719b28d5, 0x2a3bcbea), TOBN(0xee74c82b, 0x9d6ae5c6)},
+ {TOBN(0x0927d05e, 0xbaf28ee6), TOBN(0x82cecf2c, 0x9d719028),
+ TOBN(0x0b0d353e, 0xddb30289), TOBN(0xfe4bb977, 0xfddb2e29)}},
+ {{TOBN(0xbb5bb990, 0x640bfd9e), TOBN(0xd226e277, 0x82f62108),
+ TOBN(0x4bf00985, 0x02ffdd56), TOBN(0x7756758a, 0x2ca1b1b5)},
+ {TOBN(0xc32b62a3, 0x5285fe91), TOBN(0xedbc546a, 0x8c9cd140),
+ TOBN(0x1e47a013, 0xaf5cb008), TOBN(0xbca7e720, 0x073ce8f2)}},
+ {{TOBN(0xe10b2ab8, 0x17a91cae), TOBN(0xb89aab65, 0x08e27f63),
+ TOBN(0x7b3074a7, 0xdba3ddf9), TOBN(0x1c20ce09, 0x330c2972)},
+ {TOBN(0x6b9917b4, 0x5fcf7e33), TOBN(0xe6793743, 0x945ceb42),
+ TOBN(0x18fc2215, 0x5c633d19), TOBN(0xad1adb3c, 0xc7485474)}},
+ {{TOBN(0x646f9679, 0x6424c49b), TOBN(0xf888dfe8, 0x67c241c9),
+ TOBN(0xe12d4b93, 0x24f68b49), TOBN(0x9a6b62d8, 0xa571df20)},
+ {TOBN(0x81b4b26d, 0x179483cb), TOBN(0x666f9632, 0x9511fae2),
+ TOBN(0xd281b3e4, 0xd53aa51f), TOBN(0x7f96a765, 0x7f3dbd16)}},
+ {{TOBN(0xa7f8b5bf, 0x074a30ce), TOBN(0xd7f52107, 0x005a32e6),
+ TOBN(0x6f9e0907, 0x50237ed4), TOBN(0x2f21da47, 0x8096fa2b)},
+ {TOBN(0xf3e19cb4, 0xeec863a0), TOBN(0xd18f77fd, 0x9527620a),
+ TOBN(0x9505c81c, 0x407c1cf8), TOBN(0x9998db4e, 0x1b6ec284)}},
+ {{TOBN(0x7e3389e5, 0xc247d44d), TOBN(0x12507141, 0x3f4f3d80),
+ TOBN(0xd4ba0110, 0x4a78a6c7), TOBN(0x312874a0, 0x767720be)},
+ {TOBN(0xded059a6, 0x75944370), TOBN(0xd6123d90, 0x3b2c0bdd),
+ TOBN(0xa56b717b, 0x51c108e3), TOBN(0x9bb7940e, 0x070623e9)}},
+ {{TOBN(0x794e2d59, 0x84ac066c), TOBN(0xf5954a92, 0xe68c69a0),
+ TOBN(0x28c52458, 0x4fd99dcc), TOBN(0x60e639fc, 0xb1012517)},
+ {TOBN(0xc2e60125, 0x7de79248), TOBN(0xe9ef6404, 0xf12fc6d7),
+ TOBN(0x4c4f2808, 0x2a3b5d32), TOBN(0x865ad32e, 0xc768eb8a)}},
+ {{TOBN(0xac02331b, 0x13fb70b6), TOBN(0x037b44c1, 0x95599b27),
+ TOBN(0x1a860fc4, 0x60bd082c), TOBN(0xa2e25745, 0xc980cd01)},
+ {TOBN(0xee3387a8, 0x1da0263e), TOBN(0x931bfb95, 0x2d10f3d6),
+ TOBN(0x5b687270, 0xa1f24a32), TOBN(0xf140e65d, 0xca494b86)}},
+ {{TOBN(0x4f4ddf91, 0xb2f1ac7a), TOBN(0xf99eaabb, 0x760fee27),
+ TOBN(0x57f4008a, 0x49c228e5), TOBN(0x090be440, 0x1cf713bb)},
+ {TOBN(0xac91fbe4, 0x5004f022), TOBN(0xd838c2c2, 0x569e1af6),
+ TOBN(0xd6c7d20b, 0x0f1daaa5), TOBN(0xaa063ac1, 0x1bbb02c0)}},
+ {{TOBN(0x0938a422, 0x59558a78), TOBN(0x5343c669, 0x8435da2f),
+ TOBN(0x96f67b18, 0x034410dc), TOBN(0x7cc1e424, 0x84510804)},
+ {TOBN(0x86a1543f, 0x16dfbb7d), TOBN(0x921fa942, 0x5b5bd592),
+ TOBN(0x9dcccb6e, 0xb33dd03c), TOBN(0x8581ddd9, 0xb843f51e)}},
+ {{TOBN(0x54935fcb, 0x81d73c9e), TOBN(0x6d07e979, 0x0a5e97ab),
+ TOBN(0x4dc7b30a, 0xcf3a6bab), TOBN(0x147ab1f3, 0x170bee11)},
+ {TOBN(0x0aaf8e3d, 0x9fafdee4), TOBN(0xfab3dbcb, 0x538a8b95),
+ TOBN(0x405df4b3, 0x6ef13871), TOBN(0xf1f4e9cb, 0x088d5a49)}},
+ {{TOBN(0x9bcd24d3, 0x66b33f1d), TOBN(0x3b97b820, 0x5ce445c0),
+ TOBN(0xe2926549, 0xba93ff61), TOBN(0xd9c341ce, 0x4dafe616)},
+ {TOBN(0xfb30a76e, 0x16efb6f3), TOBN(0xdf24b8ca, 0x605b953c),
+ TOBN(0x8bd52afe, 0xc2fffb9f), TOBN(0xbbac5ff7, 0xe19d0b96)}},
+ {{TOBN(0x43c01b87, 0x459afccd), TOBN(0x6bd45143, 0xb7432652),
+ TOBN(0x84734530, 0x55b5d78e), TOBN(0x81088fdb, 0x1554ba7d)},
+ {TOBN(0xada0a52c, 0x1e269375), TOBN(0xf9f037c4, 0x2dc5ec10),
+ TOBN(0xc0660607, 0x94bfbc11), TOBN(0xc0a630bb, 0xc9c40d2f)}},
+ {{TOBN(0x5efc797e, 0xab64c31e), TOBN(0xffdb1dab, 0x74507144),
+ TOBN(0xf6124287, 0x1ca6790c), TOBN(0xe9609d81, 0xe69bf1bf)},
+ {TOBN(0xdb898595, 0x00d24fc9), TOBN(0x9c750333, 0xe51fb417),
+ TOBN(0x51830a91, 0xfef7bbde), TOBN(0x0ce67dc8, 0x945f585c)}},
+ {{TOBN(0x9a730ed4, 0x4763eb50), TOBN(0x24a0e221, 0xc1ab0d66),
+ TOBN(0x643b6393, 0x648748f3), TOBN(0x1982daa1, 0x6d3c6291)},
+ {TOBN(0x6f00a9f7, 0x8bbc5549), TOBN(0x7a1783e1, 0x7f36384e),
+ TOBN(0xe8346323, 0xde977f50), TOBN(0x91ab688d, 0xb245502a)}},
+ {{TOBN(0x331ab6b5, 0x6d0bdd66), TOBN(0x0a6ef32e, 0x64b71229),
+ TOBN(0x1028150e, 0xfe7c352f), TOBN(0x27e04350, 0xce7b39d3)},
+ {TOBN(0x2a3c8acd, 0xc1070c82), TOBN(0xfb2034d3, 0x80c9feef),
+ TOBN(0x2d729621, 0x709f3729), TOBN(0x8df290bf, 0x62cb4549)}},
+ {{TOBN(0x02f99f33, 0xfc2e4326), TOBN(0x3b30076d, 0x5eddf032),
+ TOBN(0xbb21f8cf, 0x0c652fb5), TOBN(0x314fb49e, 0xed91cf7b)},
+ {TOBN(0xa013eca5, 0x2f700750), TOBN(0x2b9e3c23, 0x712a4575),
+ TOBN(0xe5355557, 0xaf30fbb0), TOBN(0x1ada3516, 0x7c77e771)}},
+ {{TOBN(0x45f6ecb2, 0x7b135670), TOBN(0xe85d19df, 0x7cfc202e),
+ TOBN(0x0f1b50c7, 0x58d1be9f), TOBN(0x5ebf2c0a, 0xead2e344)},
+ {TOBN(0x1531fe4e, 0xabc199c9), TOBN(0xc7032592, 0x56bab0ae),
+ TOBN(0x16ab2e48, 0x6c1fec54), TOBN(0x0f87fda8, 0x04280188)}},
+ {{TOBN(0xdc9f46fc, 0x609e4a74), TOBN(0x2a44a143, 0xba667f91),
+ TOBN(0xbc3d8b95, 0xb4d83436), TOBN(0xa01e4bd0, 0xc7bd2958)},
+ {TOBN(0x7b182932, 0x73483c90), TOBN(0xa79c6aa1, 0xa7c7b598),
+ TOBN(0xbf3983c6, 0xeaaac07e), TOBN(0x8f18181e, 0x96e0d4e6)}},
+ {{TOBN(0x8553d37c, 0x051af62b), TOBN(0xe9a998eb, 0x0bf94496),
+ TOBN(0xe0844f9f, 0xb0d59aa1), TOBN(0x983fd558, 0xe6afb813)},
+ {TOBN(0x9670c0ca, 0x65d69804), TOBN(0x732b22de, 0x6ea5ff2d),
+ TOBN(0xd7640ba9, 0x5fd8623b), TOBN(0x9f619163, 0xa6351782)}},
+ {{TOBN(0x0bfc27ee, 0xacee5043), TOBN(0xae419e73, 0x2eb10f02),
+ TOBN(0x19c028d1, 0x8943fb05), TOBN(0x71f01cf7, 0xff13aa2a)},
+ {TOBN(0x7790737e, 0x8887a132), TOBN(0x67513309, 0x66318410),
+ TOBN(0x9819e8a3, 0x7ddb795e), TOBN(0xfecb8ef5, 0xdad100b2)}},
+ {{TOBN(0x59f74a22, 0x3021926a), TOBN(0xb7c28a49, 0x6f9b4c1c),
+ TOBN(0xed1a733f, 0x912ad0ab), TOBN(0x42a910af, 0x01a5659c)},
+ {TOBN(0x3842c6e0, 0x7bd68cab), TOBN(0x2b57fa38, 0x76d70ac8),
+ TOBN(0x8a6707a8, 0x3c53aaeb), TOBN(0x62c1c510, 0x65b4db18)}},
+ {{TOBN(0x8de2c1fb, 0xb2d09dc7), TOBN(0xc3dfed12, 0x266bd23b),
+ TOBN(0x927d039b, 0xd5b27db6), TOBN(0x2fb2f0f1, 0x103243da)},
+ {TOBN(0xf855a07b, 0x80be7399), TOBN(0xed9327ce, 0x1f9f27a8),
+ TOBN(0xa0bd99c7, 0x729bdef7), TOBN(0x2b67125e, 0x28250d88)}},
+ {{TOBN(0x784b26e8, 0x8670ced7), TOBN(0xe3dfe41f, 0xc31bd3b4),
+ TOBN(0x9e353a06, 0xbcc85cbc), TOBN(0x302e2909, 0x60178a9d)},
+ {TOBN(0x860abf11, 0xa6eac16e), TOBN(0x76447000, 0xaa2b3aac),
+ TOBN(0x46ff9d19, 0x850afdab), TOBN(0x35bdd6a5, 0xfdb2d4c1)}},
+ {{TOBN(0xe82594b0, 0x7e5c9ce9), TOBN(0x0f379e53, 0x20af346e),
+ TOBN(0x608b31e3, 0xbc65ad4a), TOBN(0x710c6b12, 0x267c4826)},
+ {TOBN(0x51c966f9, 0x71954cf1), TOBN(0xb1cec793, 0x0d0aa215),
+ TOBN(0x1f155989, 0x86bd23a8), TOBN(0xae2ff99c, 0xf9452e86)}},
+ {{TOBN(0xd8dd953c, 0x340ceaa2), TOBN(0x26355275, 0x2e2e9333),
+ TOBN(0x15d4e5f9, 0x8586f06d), TOBN(0xd6bf94a8, 0xf7cab546)},
+ {TOBN(0x33c59a0a, 0xb76a9af0), TOBN(0x52740ab3, 0xba095af7),
+ TOBN(0xc444de8a, 0x24389ca0), TOBN(0xcc6f9863, 0x706da0cb)}},
+ {{TOBN(0xb5a741a7, 0x6b2515cf), TOBN(0x71c41601, 0x9585c749),
+ TOBN(0x78350d4f, 0xe683de97), TOBN(0x31d61524, 0x63d0b5f5)},
+ {TOBN(0x7a0cc5e1, 0xfbce090b), TOBN(0xaac927ed, 0xfbcb2a5b),
+ TOBN(0xe920de49, 0x20d84c35), TOBN(0x8c06a0b6, 0x22b4de26)}},
+ {{TOBN(0xd34dd58b, 0xafe7ddf3), TOBN(0x55851fed, 0xc1e6e55b),
+ TOBN(0xd1395616, 0x960696e7), TOBN(0x940304b2, 0x5f22705f)},
+ {TOBN(0x6f43f861, 0xb0a2a860), TOBN(0xcf121282, 0x0e7cc981),
+ TOBN(0x12186212, 0x0ab64a96), TOBN(0x09215b9a, 0xb789383c)}},
+ {{TOBN(0x311eb305, 0x37387c09), TOBN(0xc5832fce, 0xf03ee760),
+ TOBN(0x30358f58, 0x32f7ea19), TOBN(0xe01d3c34, 0x91d53551)},
+ {TOBN(0x1ca5ee41, 0xda48ea80), TOBN(0x34e71e8e, 0xcf4fa4c1),
+ TOBN(0x312abd25, 0x7af1e1c7), TOBN(0xe3afcdeb, 0x2153f4a5)}},
+ {{TOBN(0x9d5c84d7, 0x00235e9a), TOBN(0x0308d3f4, 0x8c4c836f),
+ TOBN(0xc0a66b04, 0x89332de5), TOBN(0x610dd399, 0x89e566ef)},
+ {TOBN(0xf8eea460, 0xd1ac1635), TOBN(0x84cbb3fb, 0x20a2c0df),
+ TOBN(0x40afb488, 0xe74a48c5), TOBN(0x29738198, 0xd326b150)}},
+ {{TOBN(0x2a17747f, 0xa6d74081), TOBN(0x60ea4c05, 0x55a26214),
+ TOBN(0x53514bb4, 0x1f88c5fe), TOBN(0xedd64567, 0x7e83426c)},
+ {TOBN(0xd5d6cbec, 0x96460b25), TOBN(0xa12fd0ce, 0x68dc115e),
+ TOBN(0xc5bc3ed2, 0x697840ea), TOBN(0x969876a8, 0xa6331e31)}},
+ {{TOBN(0x60c36217, 0x472ff580), TOBN(0xf4229705, 0x4ad41393),
+ TOBN(0x4bd99ef0, 0xa03b8b92), TOBN(0x501c7317, 0xc144f4f6)},
+ {TOBN(0x159009b3, 0x18464945), TOBN(0x6d5e594c, 0x74c5c6be),
+ TOBN(0x2d587011, 0x321a3660), TOBN(0xd1e184b1, 0x3898d022)}},
+ {{TOBN(0x5ba04752, 0x4c6a7e04), TOBN(0x47fa1e2b, 0x45550b65),
+ TOBN(0x9419daf0, 0x48c0a9a5), TOBN(0x66362953, 0x7c243236)},
+ {TOBN(0xcd0744b1, 0x5cb12a88), TOBN(0x561b6f9a, 0x2b646188),
+ TOBN(0x599415a5, 0x66c2c0c0), TOBN(0xbe3f0859, 0x0f83f09a)}},
+ {{TOBN(0x9141c5be, 0xb92041b8), TOBN(0x01ae38c7, 0x26477d0d),
+ TOBN(0xca8b71f3, 0xd12c7a94), TOBN(0xfab5b31f, 0x765c70db)},
+ {TOBN(0x76ae7492, 0x487443e9), TOBN(0x8595a310, 0x990d1349),
+ TOBN(0xf8dbeda8, 0x7d460a37), TOBN(0x7f7ad082, 0x1e45a38f)}},
+ {{TOBN(0xed1d4db6, 0x1059705a), TOBN(0xa3dd492a, 0xe6b9c697),
+ TOBN(0x4b92ee3a, 0x6eb38bd5), TOBN(0xbab2609d, 0x67cc0bb7)},
+ {TOBN(0x7fc4fe89, 0x6e70ee82), TOBN(0xeff2c56e, 0x13e6b7e3),
+ TOBN(0x9b18959e, 0x34d26fca), TOBN(0x2517ab66, 0x889d6b45)}},
+ {{TOBN(0xf167b4e0, 0xbdefdd4f), TOBN(0x69958465, 0xf366e401),
+ TOBN(0x5aa368ab, 0xa73bbec0), TOBN(0x12148709, 0x7b240c21)},
+ {TOBN(0x378c3233, 0x18969006), TOBN(0xcb4d73ce, 0xe1fe53d1),
+ TOBN(0x5f50a80e, 0x130c4361), TOBN(0xd67f5951, 0x7ef5212b)}},
+ {{TOBN(0xf145e21e, 0x9e70c72e), TOBN(0xb2e52e29, 0x5566d2fb),
+ TOBN(0x44eaba4a, 0x032397f5), TOBN(0x5e56937b, 0x7e31a7de)},
+ {TOBN(0x68dcf517, 0x456c61e1), TOBN(0xbc2e954a, 0xa8b0a388),
+ TOBN(0xe3552fa7, 0x60a8b755), TOBN(0x03442dae, 0x73ad0cde)}},
+ {{TOBN(0x37ffe747, 0xceb26210), TOBN(0x983545e8, 0x787baef9),
+ TOBN(0x8b8c8535, 0x86a3de31), TOBN(0xc621dbcb, 0xfacd46db)},
+ {TOBN(0x82e442e9, 0x59266fbb), TOBN(0xa3514c37, 0x339d471c),
+ TOBN(0x3a11b771, 0x62cdad96), TOBN(0xf0cb3b3c, 0xecf9bdf0)}},
+ {{TOBN(0x3fcbdbce, 0x478e2135), TOBN(0x7547b5cf, 0xbda35342),
+ TOBN(0xa97e81f1, 0x8a677af6), TOBN(0xc8c2bf83, 0x28817987)},
+ {TOBN(0xdf07eaaf, 0x45580985), TOBN(0xc68d1f05, 0xc93b45cb),
+ TOBN(0x106aa2fe, 0xc77b4cac), TOBN(0x4c1d8afc, 0x04a7ae86)}},
+ {{TOBN(0xdb41c3fd, 0x9eb45ab2), TOBN(0x5b234b5b, 0xd4b22e74),
+ TOBN(0xda253dec, 0xf215958a), TOBN(0x67e0606e, 0xa04edfa0)},
+ {TOBN(0xabbbf070, 0xef751b11), TOBN(0xf352f175, 0xf6f06dce),
+ TOBN(0xdfc4b6af, 0x6839f6b4), TOBN(0x53ddf9a8, 0x9959848e)}},
+ {{TOBN(0xda49c379, 0xc21520b0), TOBN(0x90864ff0, 0xdbd5d1b6),
+ TOBN(0x2f055d23, 0x5f49c7f7), TOBN(0xe51e4e6a, 0xa796b2d8)},
+ {TOBN(0xc361a67f, 0x5c9dc340), TOBN(0x5ad53c37, 0xbca7c620),
+ TOBN(0xda1d6588, 0x32c756d0), TOBN(0xad60d911, 0x8bb67e13)}},
+ {{TOBN(0xd6c47bdf, 0x0eeec8c6), TOBN(0x4a27fec1, 0x078a1821),
+ TOBN(0x081f7415, 0xc3099524), TOBN(0x8effdf0b, 0x82cd8060)},
+ {TOBN(0xdb70ec1c, 0x65842df8), TOBN(0x8821b358, 0xd319a901),
+ TOBN(0x72ee56ee, 0xde42b529), TOBN(0x5bb39592, 0x236e4286)}},
+ {{TOBN(0xd1183316, 0xfd6f7140), TOBN(0xf9fadb5b, 0xbd8e81f7),
+ TOBN(0x701d5e0c, 0x5a02d962), TOBN(0xfdee4dbf, 0x1b601324)},
+ {TOBN(0xbed17407, 0x35d7620e), TOBN(0x04e3c2c3, 0xf48c0012),
+ TOBN(0x9ee29da7, 0x3455449a), TOBN(0x562cdef4, 0x91a836c4)}},
+ {{TOBN(0x8f682a5f, 0x47701097), TOBN(0x617125d8, 0xff88d0c2),
+ TOBN(0x948fda24, 0x57bb86dd), TOBN(0x348abb8f, 0x289f7286)},
+ {TOBN(0xeb10eab5, 0x99d94bbd), TOBN(0xd51ba28e, 0x4684d160),
+ TOBN(0xabe0e51c, 0x30c8f41a), TOBN(0x66588b45, 0x13254f4a)}},
+ {{TOBN(0x147ebf01, 0xfad097a5), TOBN(0x49883ea8, 0x610e815d),
+ TOBN(0xe44d60ba, 0x8a11de56), TOBN(0xa970de6e, 0x827a7a6d)},
+ {TOBN(0x2be41424, 0x5e17fc19), TOBN(0xd833c657, 0x01214057),
+ TOBN(0x1375813b, 0x363e723f), TOBN(0x6820bb88, 0xe6a52e9b)}},
+ {{TOBN(0x7e7f6970, 0xd875d56a), TOBN(0xd6a0a9ac, 0x51fbf6bf),
+ TOBN(0x54ba8790, 0xa3083c12), TOBN(0xebaeb23d, 0x6ae7eb64)},
+ {TOBN(0xa8685c3a, 0xb99a907a), TOBN(0xf1e74550, 0x026bf40b),
+ TOBN(0x7b73a027, 0xc802cd9e), TOBN(0x9a8a927c, 0x4fef4635)}},
+ {{TOBN(0xe1b6f60c, 0x08191224), TOBN(0xc4126ebb, 0xde4ec091),
+ TOBN(0xe1dff4dc, 0x4ae38d84), TOBN(0xde3f57db, 0x4f2ef985)},
+ {TOBN(0x34964337, 0xd446a1dd), TOBN(0x7bf217a0, 0x859e77f6),
+ TOBN(0x8ff10527, 0x8e1d13f5), TOBN(0xa304ef03, 0x74eeae27)}},
+ {{TOBN(0xfc6f5e47, 0xd19dfa5a), TOBN(0xdb007de3, 0x7fad982b),
+ TOBN(0x28205ad1, 0x613715f5), TOBN(0x251e6729, 0x7889529e)},
+ {TOBN(0x72705184, 0x1ae98e78), TOBN(0xf818537d, 0x271cac32),
+ TOBN(0xc8a15b7e, 0xb7f410f5), TOBN(0xc474356f, 0x81f62393)}},
+ {{TOBN(0x92dbdc5a, 0xc242316b), TOBN(0xabe060ac, 0xdbf4aff5),
+ TOBN(0x6e8c38fe, 0x909a8ec6), TOBN(0x43e514e5, 0x6116cb94)},
+ {TOBN(0x2078fa38, 0x07d784f9), TOBN(0x1161a880, 0xf4b5b357),
+ TOBN(0x5283ce79, 0x13adea3d), TOBN(0x0756c3e6, 0xcc6a910b)}},
+ {{TOBN(0x60bcfe01, 0xaaa79697), TOBN(0x04a73b29, 0x56391db1),
+ TOBN(0xdd8dad47, 0x189b45a0), TOBN(0xbfac0dd0, 0x48d5b8d9)},
+ {TOBN(0x34ab3af5, 0x7d3d2ec2), TOBN(0x6fa2fc2d, 0x207bd3af),
+ TOBN(0x9ff40092, 0x66550ded), TOBN(0x719b3e87, 0x1fd5b913)}},
+ {{TOBN(0xa573a496, 0x6d17fbc7), TOBN(0x0cd1a70a, 0x73d2b24e),
+ TOBN(0x34e2c5ca, 0xb2676937), TOBN(0xe7050b06, 0xbf669f21)},
+ {TOBN(0xfbe948b6, 0x1ede9046), TOBN(0xa0530051, 0x97662659),
+ TOBN(0x58cbd4ed, 0xf10124c5), TOBN(0xde2646e4, 0xdd6c06c8)}},
+ {{TOBN(0x332f8108, 0x8cad38c0), TOBN(0x471b7e90, 0x6bd68ae2),
+ TOBN(0x56ac3fb2, 0x0d8e27a3), TOBN(0xb54660db, 0x136b4b0d)},
+ {TOBN(0x123a1e11, 0xa6fd8de4), TOBN(0x44dbffea, 0xa37799ef),
+ TOBN(0x4540b977, 0xce6ac17c), TOBN(0x495173a8, 0xaf60acef)}}},
+ {{{TOBN(0x9ebb284d, 0x391c2a82), TOBN(0xbcdd4863, 0x158308e8),
+ TOBN(0x006f16ec, 0x83f1edca), TOBN(0xa13e2c37, 0x695dc6c8)},
+ {TOBN(0x2ab756f0, 0x4a057a87), TOBN(0xa8765500, 0xa6b48f98),
+ TOBN(0x4252face, 0x68651c44), TOBN(0xa52b540b, 0xe1765e02)}},
+ {{TOBN(0x4f922fc5, 0x16a0d2bb), TOBN(0x0d5cc16c, 0x1a623499),
+ TOBN(0x9241cf3a, 0x57c62c8b), TOBN(0x2f5e6961, 0xfd1b667f)},
+ {TOBN(0x5c15c70b, 0xf5a01797), TOBN(0x3d20b44d, 0x60956192),
+ TOBN(0x04911b37, 0x071fdb52), TOBN(0xf648f916, 0x8d6f0f7b)}},
+ {{TOBN(0x6dc1acaf, 0xe60b7cf7), TOBN(0x25860a50, 0x84a9d869),
+ TOBN(0x56fc6f09, 0xe7ba8ac4), TOBN(0x828c5bd0, 0x6148d29e)},
+ {TOBN(0xac6b435e, 0xdc55ae5f), TOBN(0xa527f56c, 0xc0117411),
+ TOBN(0x94d5045e, 0xfd24342c), TOBN(0x2c4c0a35, 0x70b67c0d)}},
+ {{TOBN(0x027cc8b8, 0xfac61d9a), TOBN(0x7d25e062, 0xe3c6fe8a),
+ TOBN(0xe08805bf, 0xe5bff503), TOBN(0x13271e6c, 0x6ff632f7)},
+ {TOBN(0x55dca6c0, 0x232f76a5), TOBN(0x8957c32d, 0x701ef426),
+ TOBN(0xee728bcb, 0xa10a5178), TOBN(0x5ea60411, 0xb62c5173)}},
+ {{TOBN(0xfc4e964e, 0xd0b8892b), TOBN(0x9ea17683, 0x9301bb74),
+ TOBN(0x6265c5ae, 0xfcc48626), TOBN(0xe60cf82e, 0xbb3e9102)},
+ {TOBN(0x57adf797, 0xd4df5531), TOBN(0x235b59a1, 0x8deeefe2),
+ TOBN(0x60adcf58, 0x3f306eb1), TOBN(0x105c2753, 0x3d09492d)}},
+ {{TOBN(0x4090914b, 0xb5def996), TOBN(0x1cb69c83, 0x233dd1e7),
+ TOBN(0xc1e9c1d3, 0x9b3d5e76), TOBN(0x1f3338ed, 0xfccf6012)},
+ {TOBN(0xb1e95d0d, 0x2f5378a8), TOBN(0xacf4c2c7, 0x2f00cd21),
+ TOBN(0x6e984240, 0xeb5fe290), TOBN(0xd66c038d, 0x248088ae)}},
+ {{TOBN(0x804d264a, 0xf94d70cf), TOBN(0xbdb802ef, 0x7314bf7e),
+ TOBN(0x8fb54de2, 0x4333ed02), TOBN(0x740461e0, 0x285635d9)},
+ {TOBN(0x4113b2c8, 0x365e9383), TOBN(0xea762c83, 0x3fdef652),
+ TOBN(0x4eec6e2e, 0x47b956c1), TOBN(0xa3d814be, 0x65620fa4)}},
+ {{TOBN(0x9ad5462b, 0xb4d8bc50), TOBN(0x181c0b16, 0xa9195770),
+ TOBN(0xebd4fe1c, 0x78412a68), TOBN(0xae0341bc, 0xc0dff48c)},
+ {TOBN(0xb6bc45cf, 0x7003e866), TOBN(0xf11a6dea, 0x8a24a41b),
+ TOBN(0x5407151a, 0xd04c24c2), TOBN(0x62c9d27d, 0xda5b7b68)}},
+ {{TOBN(0x2e964235, 0x88cceff6), TOBN(0x8594c54f, 0x8b07ed69),
+ TOBN(0x1578e73c, 0xc84d0d0d), TOBN(0x7b4e1055, 0xff532868)},
+ {TOBN(0xa348c0d5, 0xb5ec995a), TOBN(0xbf4b9d55, 0x14289a54),
+ TOBN(0x9ba155a6, 0x58fbd777), TOBN(0x186ed7a8, 0x1a84491d)}},
+ {{TOBN(0xd4992b30, 0x614c0900), TOBN(0xda98d121, 0xbd00c24b),
+ TOBN(0x7f534dc8, 0x7ec4bfa1), TOBN(0x4a5ff674, 0x37dc34bc)},
+ {TOBN(0x68c196b8, 0x1d7ea1d7), TOBN(0x38cf2893, 0x80a6d208),
+ TOBN(0xfd56cd09, 0xe3cbbd6e), TOBN(0xec72e27e, 0x4205a5b6)}},
+ {{TOBN(0x15ea68f5, 0xa44f77f7), TOBN(0x7aa5f9fd, 0xb43c52bc),
+ TOBN(0x86ff676f, 0x94f0e609), TOBN(0xa4cde963, 0x2e2d432b)},
+ {TOBN(0x8cafa0c0, 0xeee470af), TOBN(0x84137d0e, 0x8a3f5ec8),
+ TOBN(0xebb40411, 0xfaa31231), TOBN(0xa239c13f, 0x6f7f7ccf)}},
+ {{TOBN(0x32865719, 0xa8afd30b), TOBN(0x86798328, 0x8a826dce),
+ TOBN(0xdf04e891, 0xc4a8fbe0), TOBN(0xbb6b6e1b, 0xebf56ad3)},
+ {TOBN(0x0a695b11, 0x471f1ff0), TOBN(0xd76c3389, 0xbe15baf0),
+ TOBN(0x018edb95, 0xbe96c43e), TOBN(0xf2beaaf4, 0x90794158)}},
+ {{TOBN(0x152db09e, 0xc3076a27), TOBN(0x5e82908e, 0xe416545d),
+ TOBN(0xa2c41272, 0x356d6f2e), TOBN(0xdc9c9642, 0x31fd74e1)},
+ {TOBN(0x66ceb88d, 0x519bf615), TOBN(0xe29ecd76, 0x05a2274e),
+ TOBN(0x3a0473c4, 0xbf5e2fa0), TOBN(0x6b6eb671, 0x64284e67)}},
+ {{TOBN(0xe8b97932, 0xb88756dd), TOBN(0xed4e8652, 0xf17e3e61),
+ TOBN(0xc2dd1499, 0x3ee1c4a4), TOBN(0xc0aaee17, 0x597f8c0e)},
+ {TOBN(0x15c4edb9, 0x6c168af3), TOBN(0x6563c7bf, 0xb39ae875),
+ TOBN(0xadfadb6f, 0x20adb436), TOBN(0xad55e8c9, 0x9a042ac0)}},
+ {{TOBN(0x975a1ed8, 0xb76da1f5), TOBN(0x10dfa466, 0xa58acb94),
+ TOBN(0x8dd7f7e3, 0xac060282), TOBN(0x6813e66a, 0x572a051e)},
+ {TOBN(0xb4ccae1e, 0x350cb901), TOBN(0xb653d656, 0x50cb7822),
+ TOBN(0x42484710, 0xdfab3b87), TOBN(0xcd7ee537, 0x9b670fd0)}},
+ {{TOBN(0x0a50b12e, 0x523b8bf6), TOBN(0x8009eb5b, 0x8f910c1b),
+ TOBN(0xf535af82, 0x4a167588), TOBN(0x0f835f9c, 0xfb2a2abd)},
+ {TOBN(0xf59b2931, 0x2afceb62), TOBN(0xc797df2a, 0x169d383f),
+ TOBN(0xeb3f5fb0, 0x66ac02b0), TOBN(0x029d4c6f, 0xdaa2d0ca)}},
+ {{TOBN(0xd4059bc1, 0xafab4bc5), TOBN(0x833f5c6f, 0x56783247),
+ TOBN(0xb5346630, 0x8d2d3605), TOBN(0x83387891, 0xd34d8433)},
+ {TOBN(0xd973b30f, 0xadd9419a), TOBN(0xbcca1099, 0xafe3fce8),
+ TOBN(0x08178315, 0x0809aac6), TOBN(0x01b7f21a, 0x540f0f11)}},
+ {{TOBN(0x65c29219, 0x909523c8), TOBN(0xa62f648f, 0xa3a1c741),
+ TOBN(0x88598d4f, 0x60c9e55a), TOBN(0xbce9141b, 0x0e4f347a)},
+ {TOBN(0x9af97d84, 0x35f9b988), TOBN(0x0210da62, 0x320475b6),
+ TOBN(0x3c076e22, 0x9191476c), TOBN(0x7520dbd9, 0x44fc7834)}},
+ {{TOBN(0x6a6b2cfe, 0xc1ab1bbd), TOBN(0xef8a65be, 0xdc650938),
+ TOBN(0x72855540, 0x805d7bc4), TOBN(0xda389396, 0xed11fdfd)},
+ {TOBN(0xa9d5bd36, 0x74660876), TOBN(0x11d67c54, 0xb45dff35),
+ TOBN(0x6af7d148, 0xa4f5da94), TOBN(0xbb8d4c3f, 0xc0bbeb31)}},
+ {{TOBN(0x87a7ebd1, 0xe0a1b12a), TOBN(0x1e4ef88d, 0x770ba95f),
+ TOBN(0x8c33345c, 0xdc2ae9cb), TOBN(0xcecf1276, 0x01cc8403)},
+ {TOBN(0x687c012e, 0x1b39b80f), TOBN(0xfd90d0ad, 0x35c33ba4),
+ TOBN(0xa3ef5a67, 0x5c9661c2), TOBN(0x368fc88e, 0xe017429e)}},
+ {{TOBN(0xd30c6761, 0x196a2fa2), TOBN(0x931b9817, 0xbd5b312e),
+ TOBN(0xba01000c, 0x72f54a31), TOBN(0xa203d2c8, 0x66eaa541)},
+ {TOBN(0xf2abdee0, 0x98939db3), TOBN(0xe37d6c2c, 0x3e606c02),
+ TOBN(0xf2921574, 0x521ff643), TOBN(0x2781b3c4, 0xd7e2fca3)}},
+ {{TOBN(0x664300b0, 0x7850ec06), TOBN(0xac5a38b9, 0x7d3a10cf),
+ TOBN(0x9233188d, 0xe34ab39d), TOBN(0xe77057e4, 0x5072cbb9)},
+ {TOBN(0xbcf0c042, 0xb59e78df), TOBN(0x4cfc91e8, 0x1d97de52),
+ TOBN(0x4661a26c, 0x3ee0ca4a), TOBN(0x5620a4c1, 0xfb8507bc)}},
+ {{TOBN(0x4b44d4aa, 0x049f842c), TOBN(0xceabc5d5, 0x1540e82b),
+ TOBN(0x306710fd, 0x15c6f156), TOBN(0xbe5ae52b, 0x63db1d72)},
+ {TOBN(0x06f1e7e6, 0x334957f1), TOBN(0x57e388f0, 0x31144a70),
+ TOBN(0xfb69bb2f, 0xdf96447b), TOBN(0x0f78ebd3, 0x73e38a12)}},
+ {{TOBN(0xb8222605, 0x2b7ce542), TOBN(0xe6d4ce99, 0x7472bde1),
+ TOBN(0x53e16ebe, 0x09d2f4da), TOBN(0x180ff42e, 0x53b92b2e)},
+ {TOBN(0xc59bcc02, 0x2c34a1c6), TOBN(0x3803d6f9, 0x422c46c2),
+ TOBN(0x18aff74f, 0x5c14a8a2), TOBN(0x55aebf80, 0x10a08b28)}},
+ {{TOBN(0x66097d58, 0x7135593f), TOBN(0x32e6eff7, 0x2be570cd),
+ TOBN(0x584e6a10, 0x2a8c860d), TOBN(0xcd185890, 0xa2eb4163)},
+ {TOBN(0x7ceae99d, 0x6d97e134), TOBN(0xd42c6b70, 0xdd8447ce),
+ TOBN(0x59ddbb4a, 0xb8c50273), TOBN(0x03c612df, 0x3cf34e1e)}},
+ {{TOBN(0x84b9ca15, 0x04b6c5a0), TOBN(0x35216f39, 0x18f0e3a3),
+ TOBN(0x3ec2d2bc, 0xbd986c00), TOBN(0x8bf546d9, 0xd19228fe)},
+ {TOBN(0xd1c655a4, 0x4cd623c3), TOBN(0x366ce718, 0x502b8e5a),
+ TOBN(0x2cfc84b4, 0xeea0bfe7), TOBN(0xe01d5cee, 0xcf443e8e)}},
+ {{TOBN(0x8ec045d9, 0x036520f8), TOBN(0xdfb3c3d1, 0x92d40e98),
+ TOBN(0x0bac4cce, 0xcc559a04), TOBN(0x35eccae5, 0x240ea6b1)},
+ {TOBN(0x180b32db, 0xf8a5a0ac), TOBN(0x547972a5, 0xeb699700),
+ TOBN(0xa3765801, 0xca26bca0), TOBN(0x57e09d0e, 0xa647f25a)}},
+ {{TOBN(0xb956970e, 0x2fdd23cc), TOBN(0xb80288bc, 0x5682e971),
+ TOBN(0xe6e6d91e, 0x9ae86ebc), TOBN(0x0564c83f, 0x8c9f1939)},
+ {TOBN(0x551932a2, 0x39560368), TOBN(0xe893752b, 0x049c28e2),
+ TOBN(0x0b03cee5, 0xa6a158c3), TOBN(0xe12d656b, 0x04964263)}},
+ {{TOBN(0x4b47554e, 0x63e3bc1d), TOBN(0xc719b6a2, 0x45044ff7),
+ TOBN(0x4f24d30a, 0xe48daa07), TOBN(0xa3f37556, 0xc8c1edc3)},
+ {TOBN(0x9a47bf76, 0x0700d360), TOBN(0xbb1a1824, 0x822ae4e2),
+ TOBN(0x22e275a3, 0x89f1fb4c), TOBN(0x72b1aa23, 0x9968c5f5)}},
+ {{TOBN(0xa75feaca, 0xbe063f64), TOBN(0x9b392f43, 0xbce47a09),
+ TOBN(0xd4241509, 0x1ad07aca), TOBN(0x4b0c591b, 0x8d26cd0f)},
+ {TOBN(0x2d42ddfd, 0x92f1169a), TOBN(0x63aeb1ac, 0x4cbf2392),
+ TOBN(0x1de9e877, 0x0691a2af), TOBN(0xebe79af7, 0xd98021da)}},
+ {{TOBN(0xcfdf2a4e, 0x40e50acf), TOBN(0xf0a98ad7, 0xaf01d665),
+ TOBN(0xefb640bf, 0x1831be1f), TOBN(0x6fe8bd2f, 0x80e9ada0)},
+ {TOBN(0x94c103a1, 0x6cafbc91), TOBN(0x170f8759, 0x8308e08c),
+ TOBN(0x5de2d2ab, 0x9780ff4f), TOBN(0x666466bc, 0x45b201f2)}},
+ {{TOBN(0x58af2010, 0xf5b343bc), TOBN(0x0f2e400a, 0xf2f142fe),
+ TOBN(0x3483bfde, 0xa85f4bdf), TOBN(0xf0b1d093, 0x03bfeaa9)},
+ {TOBN(0x2ea01b95, 0xc7081603), TOBN(0xe943e4c9, 0x3dba1097),
+ TOBN(0x47be92ad, 0xb438f3a6), TOBN(0x00bb7742, 0xe5bf6636)}},
+ {{TOBN(0x136b7083, 0x824297b4), TOBN(0x9d0e5580, 0x5584455f),
+ TOBN(0xab48cedc, 0xf1c7d69e), TOBN(0x53a9e481, 0x2a256e76)},
+ {TOBN(0x0402b0e0, 0x65eb2413), TOBN(0xdadbbb84, 0x8fc407a7),
+ TOBN(0xa65cd5a4, 0x8d7f5492), TOBN(0x21d44293, 0x74bae294)}},
+ {{TOBN(0x66917ce6, 0x3b5f1cc4), TOBN(0x37ae52ea, 0xce872e62),
+ TOBN(0xbb087b72, 0x2905f244), TOBN(0x12077086, 0x1e6af74f)},
+ {TOBN(0x4b644e49, 0x1058edea), TOBN(0x827510e3, 0xb638ca1d),
+ TOBN(0x8cf2b704, 0x6038591c), TOBN(0xffc8b47a, 0xfe635063)}},
+ {{TOBN(0x3ae220e6, 0x1b4d5e63), TOBN(0xbd864742, 0x9d961b4b),
+ TOBN(0x610c107e, 0x9bd16bed), TOBN(0x4270352a, 0x1127147b)},
+ {TOBN(0x7d17ffe6, 0x64cfc50e), TOBN(0x50dee01a, 0x1e36cb42),
+ TOBN(0x068a7622, 0x35dc5f9a), TOBN(0x9a08d536, 0xdf53f62c)}},
+ {{TOBN(0x4ed71457, 0x6be5f7de), TOBN(0xd93006f8, 0xc2263c9e),
+ TOBN(0xe073694c, 0xcacacb36), TOBN(0x2ff7a5b4, 0x3ae118ab)},
+ {TOBN(0x3cce53f1, 0xcd871236), TOBN(0xf156a39d, 0xc2aa6d52),
+ TOBN(0x9cc5f271, 0xb198d76d), TOBN(0xbc615b6f, 0x81383d39)}},
+ {{TOBN(0xa54538e8, 0xde3eee6b), TOBN(0x58c77538, 0xab910d91),
+ TOBN(0x31e5bdbc, 0x58d278bd), TOBN(0x3cde4adf, 0xb963acae)},
+ {TOBN(0xb1881fd2, 0x5302169c), TOBN(0x8ca60fa0, 0xa989ed8b),
+ TOBN(0xa1999458, 0xff96a0ee), TOBN(0xc1141f03, 0xac6c283d)}},
+ {{TOBN(0x7677408d, 0x6dfafed3), TOBN(0x33a01653, 0x39661588),
+ TOBN(0x3c9c15ec, 0x0b726fa0), TOBN(0x090cfd93, 0x6c9b56da)},
+ {TOBN(0xe34f4bae, 0xa3c40af5), TOBN(0x3469eadb, 0xd21129f1),
+ TOBN(0xcc51674a, 0x1e207ce8), TOBN(0x1e293b24, 0xc83b1ef9)}},
+ {{TOBN(0x17173d13, 0x1e6c0bb4), TOBN(0x19004695, 0x90776d35),
+ TOBN(0xe7980e34, 0x6de6f922), TOBN(0x873554cb, 0xf4dd9a22)},
+ {TOBN(0x0316c627, 0xcbf18a51), TOBN(0x4d93651b, 0x3032c081),
+ TOBN(0x207f2771, 0x3946834d), TOBN(0x2c08d7b4, 0x30cdbf80)}},
+ {{TOBN(0x137a4fb4, 0x86df2a61), TOBN(0xa1ed9c07, 0xecf7b4a2),
+ TOBN(0xb2e460e2, 0x7bd042ff), TOBN(0xb7f5e2fa, 0x5f62f5ec)},
+ {TOBN(0x7aa6ec6b, 0xcc2423b7), TOBN(0x75ce0a7f, 0xba63eea7),
+ TOBN(0x67a45fb1, 0xf250a6e1), TOBN(0x93bc919c, 0xe53cdc9f)}},
+ {{TOBN(0x9271f56f, 0x871942df), TOBN(0x2372ff6f, 0x7859ad66),
+ TOBN(0x5f4c2b96, 0x33cb1a78), TOBN(0xe3e29101, 0x5838aa83)},
+ {TOBN(0xa7ed1611, 0xe4e8110c), TOBN(0x2a2d70d5, 0x330198ce),
+ TOBN(0xbdf132e8, 0x6720efe0), TOBN(0xe61a8962, 0x66a471bf)}},
+ {{TOBN(0x796d3a85, 0x825808bd), TOBN(0x51dc3cb7, 0x3fd6e902),
+ TOBN(0x643c768a, 0x916219d1), TOBN(0x36cd7685, 0xa2ad7d32)},
+ {TOBN(0xe3db9d05, 0xb22922a4), TOBN(0x6494c87e, 0xdba29660),
+ TOBN(0xf0ac91df, 0xbcd2ebc7), TOBN(0x4deb57a0, 0x45107f8d)}},
+ {{TOBN(0x42271f59, 0xc3d12a73), TOBN(0x5f71687c, 0xa5c2c51d),
+ TOBN(0xcb1f50c6, 0x05797bcb), TOBN(0x29ed0ed9, 0xd6d34eb0)},
+ {TOBN(0xe5fe5b47, 0x4683c2eb), TOBN(0x4956eeb5, 0x97447c46),
+ TOBN(0x5b163a43, 0x71207167), TOBN(0x93fa2fed, 0x0248c5ef)}},
+ {{TOBN(0x67930af2, 0x31f63950), TOBN(0xa77797c1, 0x14caa2c9),
+ TOBN(0x526e80ee, 0x27ac7e62), TOBN(0xe1e6e626, 0x58b28aec)},
+ {TOBN(0x636178b0, 0xb3c9fef0), TOBN(0xaf7752e0, 0x6d5f90be),
+ TOBN(0x94ecaf18, 0xeece51cf), TOBN(0x2864d0ed, 0xca806e1f)}},
+ {{TOBN(0x6de2e383, 0x97c69134), TOBN(0x5a42c316, 0xeb291293),
+ TOBN(0xc7779219, 0x6a60bae0), TOBN(0xa24de346, 0x6b7599d1)},
+ {TOBN(0x49d374aa, 0xb75d4941), TOBN(0x98900586, 0x2d501ff0),
+ TOBN(0x9f16d40e, 0xeb7974cf), TOBN(0x1033860b, 0xcdd8c115)}},
+ {{TOBN(0xb6c69ac8, 0x2094cec3), TOBN(0x9976fb88, 0x403b770c),
+ TOBN(0x1dea026c, 0x4859590d), TOBN(0xb6acbb46, 0x8562d1fd)},
+ {TOBN(0x7cd6c461, 0x44569d85), TOBN(0xc3190a36, 0x97f0891d),
+ TOBN(0xc6f53195, 0x48d5a17d), TOBN(0x7d919966, 0xd749abc8)}},
+ {{TOBN(0x65104837, 0xdd1c8a20), TOBN(0x7e5410c8, 0x2f683419),
+ TOBN(0x958c3ca8, 0xbe94022e), TOBN(0x605c3197, 0x6145dac2)},
+ {TOBN(0x3fc07501, 0x01683d54), TOBN(0x1d7127c5, 0x595b1234),
+ TOBN(0x10b8f87c, 0x9481277f), TOBN(0x677db2a8, 0xe65a1adb)}},
+ {{TOBN(0xec2fccaa, 0xddce3345), TOBN(0x2a6811b7, 0x012a4350),
+ TOBN(0x96760ff1, 0xac598bdc), TOBN(0x054d652a, 0xd1bf4128)},
+ {TOBN(0x0a1151d4, 0x92a21005), TOBN(0xad7f3971, 0x33110fdf),
+ TOBN(0x8c95928c, 0x1960100f), TOBN(0x6c91c825, 0x7bf03362)}},
+ {{TOBN(0xc8c8b2a2, 0xce309f06), TOBN(0xfdb27b59, 0xca27204b),
+ TOBN(0xd223eaa5, 0x0848e32e), TOBN(0xb93e4b2e, 0xe7bfaf1e)},
+ {TOBN(0xc5308ae6, 0x44aa3ded), TOBN(0x317a666a, 0xc015d573),
+ TOBN(0xc888ce23, 0x1a979707), TOBN(0xf141c1e6, 0x0d5c4958)}},
+ {{TOBN(0xb53b7de5, 0x61906373), TOBN(0x858dbade, 0xeb999595),
+ TOBN(0x8cbb47b2, 0xa59e5c36), TOBN(0x660318b3, 0xdcf4e842)},
+ {TOBN(0xbd161ccd, 0x12ba4b7a), TOBN(0xf399daab, 0xf8c8282a),
+ TOBN(0x1587633a, 0xeeb2130d), TOBN(0xa465311a, 0xda38dd7d)}},
+ {{TOBN(0x5f75eec8, 0x64d3779b), TOBN(0x3c5d0476, 0xad64c171),
+ TOBN(0x87410371, 0x2a914428), TOBN(0x8096a891, 0x90e2fc29)},
+ {TOBN(0xd3d2ae9d, 0x23b3ebc2), TOBN(0x90bdd6db, 0xa580cfd6),
+ TOBN(0x52dbb7f3, 0xc5b01f6c), TOBN(0xe68eded4, 0xe102a2dc)}},
+ {{TOBN(0x17785b77, 0x99eb6df0), TOBN(0x26c3cc51, 0x7386b779),
+ TOBN(0x345ed988, 0x6417a48e), TOBN(0xe990b4e4, 0x07d6ef31)},
+ {TOBN(0x0f456b7e, 0x2586abba), TOBN(0x239ca6a5, 0x59c96e9a),
+ TOBN(0xe327459c, 0xe2eb4206), TOBN(0x3a4c3313, 0xa002b90a)}},
+ {{TOBN(0x2a114806, 0xf6a3f6fb), TOBN(0xad5cad2f, 0x85c251dd),
+ TOBN(0x92c1f613, 0xf5a784d3), TOBN(0xec7bfacf, 0x349766d5)},
+ {TOBN(0x04b3cd33, 0x3e23cb3b), TOBN(0x3979fe84, 0xc5a64b2d),
+ TOBN(0x192e2720, 0x7e589106), TOBN(0xa60c43d1, 0xa15b527f)}},
+ {{TOBN(0x2dae9082, 0xbe7cf3a6), TOBN(0xcc86ba92, 0xbc967274),
+ TOBN(0xf28a2ce8, 0xaea0a8a9), TOBN(0x404ca6d9, 0x6ee988b3)},
+ {TOBN(0xfd7e9c5d, 0x005921b8), TOBN(0xf56297f1, 0x44e79bf9),
+ TOBN(0xa163b460, 0x0d75ddc2), TOBN(0x30b23616, 0xa1f2be87)}},
+ {{TOBN(0x4b070d21, 0xbfe50e2b), TOBN(0x7ef8cfd0, 0xe1bfede1),
+ TOBN(0xadba0011, 0x2aac4ae0), TOBN(0x2a3e7d01, 0xb9ebd033)},
+ {TOBN(0x995277ec, 0xe38d9d1c), TOBN(0xb500249e, 0x9c5d2de3),
+ TOBN(0x8912b820, 0xf13ca8c9), TOBN(0xc8798114, 0x877793af)}},
+ {{TOBN(0x19e6125d, 0xec3f1dec), TOBN(0x07b1f040, 0x911178da),
+ TOBN(0xd93ededa, 0x904a6738), TOBN(0x55187a5a, 0x0bebedcd)},
+ {TOBN(0xf7d04722, 0xeb329d41), TOBN(0xf449099e, 0xf170b391),
+ TOBN(0xfd317a69, 0xca99f828), TOBN(0x50c3db2b, 0x34a4976d)}},
+ {{TOBN(0xe9ba7784, 0x3757b392), TOBN(0x326caefd, 0xaa3ca05a),
+ TOBN(0x78e5293b, 0xf1e593d4), TOBN(0x7842a937, 0x0d98fd13)},
+ {TOBN(0xe694bf96, 0x5f96b10d), TOBN(0x373a9df6, 0x06a8cd05),
+ TOBN(0x997d1e51, 0xe8f0c7fc), TOBN(0x1d019790, 0x63fd972e)}},
+ {{TOBN(0x0064d858, 0x5499fb32), TOBN(0x7b67bad9, 0x77a8aeb7),
+ TOBN(0x1d3eb977, 0x2d08eec5), TOBN(0x5fc047a6, 0xcbabae1d)},
+ {TOBN(0x0577d159, 0xe54a64bb), TOBN(0x8862201b, 0xc43497e4),
+ TOBN(0xad6b4e28, 0x2ce0608d), TOBN(0x8b687b7d, 0x0b167aac)}},
+ {{TOBN(0x6ed4d367, 0x8b2ecfa9), TOBN(0x24dfe62d, 0xa90c3c38),
+ TOBN(0xa1862e10, 0x3fe5c42b), TOBN(0x1ca73dca, 0xd5732a9f)},
+ {TOBN(0x35f038b7, 0x76bb87ad), TOBN(0x674976ab, 0xf242b81f),
+ TOBN(0x4f2bde7e, 0xb0fd90cd), TOBN(0x6efc172e, 0xa7fdf092)}},
+ {{TOBN(0x3806b69b, 0x92222f1f), TOBN(0x5a2459ca, 0x6cf7ae70),
+ TOBN(0x6789f69c, 0xa85217ee), TOBN(0x5f232b5e, 0xe3dc85ac)},
+ {TOBN(0x660e3ec5, 0x48e9e516), TOBN(0x124b4e47, 0x3197eb31),
+ TOBN(0x10a0cb13, 0xaafcca23), TOBN(0x7bd63ba4, 0x8213224f)}},
+ {{TOBN(0xaffad7cc, 0x290a7f4f), TOBN(0x6b409c9e, 0x0286b461),
+ TOBN(0x58ab809f, 0xffa407af), TOBN(0xc3122eed, 0xc68ac073)},
+ {TOBN(0x17bf9e50, 0x4ef24d7e), TOBN(0x5d929794, 0x3e2a5811),
+ TOBN(0x519bc867, 0x02902e01), TOBN(0x76bba5da, 0x39c8a851)}},
+ {{TOBN(0xe9f9669c, 0xda94951e), TOBN(0x4b6af58d, 0x66b8d418),
+ TOBN(0xfa321074, 0x17d426a4), TOBN(0xc78e66a9, 0x9dde6027)},
+ {TOBN(0x0516c083, 0x4a53b964), TOBN(0xfc659d38, 0xff602330),
+ TOBN(0x0ab55e5c, 0x58c5c897), TOBN(0x985099b2, 0x838bc5df)}},
+ {{TOBN(0x061d9efc, 0xc52fc238), TOBN(0x712b2728, 0x6ac1da3f),
+ TOBN(0xfb658149, 0x9283fe08), TOBN(0x4954ac94, 0xb8aaa2f7)},
+ {TOBN(0x85c0ada4, 0x7fb2e74f), TOBN(0xee8ba98e, 0xb89926b0),
+ TOBN(0xe4f9d37d, 0x23d1af5b), TOBN(0x14ccdbf9, 0xba9b015e)}},
+ {{TOBN(0xb674481b, 0x7bfe7178), TOBN(0x4e1debae, 0x65405868),
+ TOBN(0x061b2821, 0xc48c867d), TOBN(0x69c15b35, 0x513b30ea)},
+ {TOBN(0x3b4a1666, 0x36871088), TOBN(0xe5e29f5d, 0x1220b1ff),
+ TOBN(0x4b82bb35, 0x233d9f4d), TOBN(0x4e076333, 0x18cdc675)}}},
+ {{{TOBN(0x0d53f5c7, 0xa3e6fced), TOBN(0xe8cbbdd5, 0xf45fbdeb),
+ TOBN(0xf85c01df, 0x13339a70), TOBN(0x0ff71880, 0x142ceb81)},
+ {TOBN(0x4c4e8774, 0xbd70437a), TOBN(0x5fb32891, 0xba0bda6a),
+ TOBN(0x1cdbebd2, 0xf18bd26e), TOBN(0x2f9526f1, 0x03a9d522)}},
+ {{TOBN(0x40ce3051, 0x92c4d684), TOBN(0x8b04d725, 0x7612efcd),
+ TOBN(0xb9dcda36, 0x6f9cae20), TOBN(0x0edc4d24, 0xf058856c)},
+ {TOBN(0x64f2e6bf, 0x85427900), TOBN(0x3de81295, 0xdc09dfea),
+ TOBN(0xd41b4487, 0x379bf26c), TOBN(0x50b62c6d, 0x6df135a9)}},
+ {{TOBN(0xd4f8e3b4, 0xc72dfe67), TOBN(0xc416b0f6, 0x90e19fdf),
+ TOBN(0x18b9098d, 0x4c13bd35), TOBN(0xac11118a, 0x15b8cb9e)},
+ {TOBN(0xf598a318, 0xf0062841), TOBN(0xbfe0602f, 0x89f356f4),
+ TOBN(0x7ae3637e, 0x30177a0c), TOBN(0x34097747, 0x61136537)}},
+ {{TOBN(0x0db2fb5e, 0xd005832a), TOBN(0x5f5efd3b, 0x91042e4f),
+ TOBN(0x8c4ffdc6, 0xed70f8ca), TOBN(0xe4645d0b, 0xb52da9cc)},
+ {TOBN(0x9596f58b, 0xc9001d1f), TOBN(0x52c8f0bc, 0x4e117205),
+ TOBN(0xfd4aa0d2, 0xe398a084), TOBN(0x815bfe3a, 0x104f49de)}},
+ {{TOBN(0x97e5443f, 0x23885e5f), TOBN(0xf72f8f99, 0xe8433aab),
+ TOBN(0xbd00b154, 0xe4d4e604), TOBN(0xd0b35e6a, 0xe5e173ff)},
+ {TOBN(0x57b2a048, 0x9164722d), TOBN(0x3e3c665b, 0x88761ec8),
+ TOBN(0x6bdd1397, 0x3da83832), TOBN(0x3c8b1a1e, 0x73dafe3b)}},
+ {{TOBN(0x4497ace6, 0x54317cac), TOBN(0xbe600ab9, 0x521771b3),
+ TOBN(0xb42e409e, 0xb0dfe8b8), TOBN(0x386a67d7, 0x3942310f)},
+ {TOBN(0x25548d8d, 0x4431cc28), TOBN(0xa7cff142, 0x985dc524),
+ TOBN(0x4d60f5a1, 0x93c4be32), TOBN(0x83ebd5c8, 0xd071c6e1)}},
+ {{TOBN(0xba3a80a7, 0xb1fd2b0b), TOBN(0x9b3ad396, 0x5bec33e8),
+ TOBN(0xb3868d61, 0x79743fb3), TOBN(0xcfd169fc, 0xfdb462fa)},
+ {TOBN(0xd3b499d7, 0x9ce0a6af), TOBN(0x55dc1cf1, 0xe42d3ff8),
+ TOBN(0x04fb9e6c, 0xc6c3e1b2), TOBN(0x47e6961d, 0x6f69a474)}},
+ {{TOBN(0x54eb3acc, 0xe548b37b), TOBN(0xb38e7542, 0x84d40549),
+ TOBN(0x8c3daa51, 0x7b341b4f), TOBN(0x2f6928ec, 0x690bf7fa)},
+ {TOBN(0x0496b323, 0x86ce6c41), TOBN(0x01be1c55, 0x10adadcd),
+ TOBN(0xc04e67e7, 0x4bb5faf9), TOBN(0x3cbaf678, 0xe15c9985)}},
+ {{TOBN(0x8cd12145, 0x50ca4247), TOBN(0xba1aa47a, 0xe7dd30aa),
+ TOBN(0x2f81ddf1, 0xe58fee24), TOBN(0x03452936, 0xeec9b0e8)},
+ {TOBN(0x8bdc3b81, 0x243aea96), TOBN(0x9a2919af, 0x15c3d0e5),
+ TOBN(0x9ea640ec, 0x10948361), TOBN(0x5ac86d5b, 0x6e0bcccf)}},
+ {{TOBN(0xf892d918, 0xc36cf440), TOBN(0xaed3e837, 0xc939719c),
+ TOBN(0xb07b08d2, 0xc0218b64), TOBN(0x6f1bcbba, 0xce9790dd)},
+ {TOBN(0x4a84d6ed, 0x60919b8e), TOBN(0xd8900791, 0x8ac1f9eb),
+ TOBN(0xf84941aa, 0x0dd5daef), TOBN(0xb22fe40a, 0x67fd62c5)}},
+ {{TOBN(0x97e15ba2, 0x157f2db3), TOBN(0xbda2fc8f, 0x8e28ca9c),
+ TOBN(0x5d050da4, 0x37b9f454), TOBN(0x3d57eb57, 0x2379d72e)},
+ {TOBN(0xe9b5eba2, 0xfb5ee997), TOBN(0x01648ca2, 0xe11538ca),
+ TOBN(0x32bb76f6, 0xf6327974), TOBN(0x338f14b8, 0xff3f4bb7)}},
+ {{TOBN(0x524d226a, 0xd7ab9a2d), TOBN(0x9c00090d, 0x7dfae958),
+ TOBN(0x0ba5f539, 0x8751d8c2), TOBN(0x8afcbcdd, 0x3ab8262d)},
+ {TOBN(0x57392729, 0xe99d043b), TOBN(0xef51263b, 0xaebc943a),
+ TOBN(0x9feace93, 0x20862935), TOBN(0x639efc03, 0xb06c817b)}},
+ {{TOBN(0x1fe054b3, 0x66b4be7a), TOBN(0x3f25a9de, 0x84a37a1e),
+ TOBN(0xf39ef1ad, 0x78d75cd9), TOBN(0xd7b58f49, 0x5062c1b5)},
+ {TOBN(0x6f74f9a9, 0xff563436), TOBN(0xf718ff29, 0xe8af51e7),
+ TOBN(0x5234d313, 0x15e97fec), TOBN(0xb6a8e2b1, 0x292f1c0a)}},
+ {{TOBN(0xa7f53aa8, 0x327720c1), TOBN(0x956ca322, 0xba092cc8),
+ TOBN(0x8f03d64a, 0x28746c4d), TOBN(0x51fe1782, 0x66d0d392)},
+ {TOBN(0xd19b34db, 0x3c832c80), TOBN(0x60dccc5c, 0x6da2e3b4),
+ TOBN(0x245dd62e, 0x0a104ccc), TOBN(0xa7ab1de1, 0x620b21fd)}},
+ {{TOBN(0xb293ae0b, 0x3893d123), TOBN(0xf7b75783, 0xb15ee71c),
+ TOBN(0x5aa3c614, 0x42a9468b), TOBN(0xd686123c, 0xdb15d744)},
+ {TOBN(0x8c616891, 0xa7ab4116), TOBN(0x6fcd72c8, 0xa4e6a459),
+ TOBN(0xac219110, 0x77e5fad7), TOBN(0xfb6a20e7, 0x704fa46b)}},
+ {{TOBN(0xe839be7d, 0x341d81dc), TOBN(0xcddb6889, 0x32148379),
+ TOBN(0xda6211a1, 0xf7026ead), TOBN(0xf3b2575f, 0xf4d1cc5e)},
+ {TOBN(0x40cfc8f6, 0xa7a73ae6), TOBN(0x83879a5e, 0x61d5b483),
+ TOBN(0xc5acb1ed, 0x41a50ebc), TOBN(0x59a60cc8, 0x3c07d8fa)}},
+ {{TOBN(0x1b73bdce, 0xb1876262), TOBN(0x2b0d79f0, 0x12af4ee9),
+ TOBN(0x8bcf3b0b, 0xd46e1d07), TOBN(0x17d6af9d, 0xe45d152f)},
+ {TOBN(0x73520461, 0x6d736451), TOBN(0x43cbbd97, 0x56b0bf5a),
+ TOBN(0xb0833a5b, 0xd5999b9d), TOBN(0x702614f0, 0xeb72e398)}},
+ {{TOBN(0x0aadf01a, 0x59c3e9f8), TOBN(0x40200e77, 0xce6b3d16),
+ TOBN(0xda22bdd3, 0xdeddafad), TOBN(0x76dedaf4, 0x310d72e1)},
+ {TOBN(0x49ef807c, 0x4bc2e88f), TOBN(0x6ba81291, 0x146dd5a5),
+ TOBN(0xa1a4077a, 0x7d8d59e9), TOBN(0x87b6a2e7, 0x802db349)}},
+ {{TOBN(0xd5679997, 0x1b4e598e), TOBN(0xf499ef1f, 0x06fe4b1d),
+ TOBN(0x3978d3ae, 0xfcb267c5), TOBN(0xb582b557, 0x235786d0)},
+ {TOBN(0x32b3b2ca, 0x1715cb07), TOBN(0x4c3de6a2, 0x8480241d),
+ TOBN(0x63b5ffed, 0xcb571ecd), TOBN(0xeaf53900, 0xed2fe9a9)}},
+ {{TOBN(0xdec98d4a, 0xc3b81990), TOBN(0x1cb83722, 0x9e0cc8fe),
+ TOBN(0xfe0b0491, 0xd2b427b9), TOBN(0x0f2386ac, 0xe983a66c)},
+ {TOBN(0x930c4d1e, 0xb3291213), TOBN(0xa2f82b2e, 0x59a62ae4),
+ TOBN(0x77233853, 0xf93e89e3), TOBN(0x7f8063ac, 0x11777c7f)}},
+ {{TOBN(0xff0eb567, 0x59ad2877), TOBN(0x6f454642, 0x9865c754),
+ TOBN(0xe6fe701a, 0x236e9a84), TOBN(0xc586ef16, 0x06e40fc3)},
+ {TOBN(0x3f62b6e0, 0x24bafad9), TOBN(0xc8b42bd2, 0x64da906a),
+ TOBN(0xc98e1eb4, 0xda3276a0), TOBN(0x30d0e5fc, 0x06cbf852)}},
+ {{TOBN(0x1b6b2ae1, 0xe8b4dfd4), TOBN(0xd754d5c7, 0x8301cbac),
+ TOBN(0x66097629, 0x112a39ac), TOBN(0xf86b5999, 0x93ba4ab9)},
+ {TOBN(0x26c9dea7, 0x99f9d581), TOBN(0x0473b1a8, 0xc2fafeaa),
+ TOBN(0x1469af55, 0x3b2505a5), TOBN(0x227d16d7, 0xd6a43323)}},
+ {{TOBN(0x3316f73c, 0xad3d97f9), TOBN(0x52bf3bb5, 0x1f137455),
+ TOBN(0x953eafeb, 0x09954e7c), TOBN(0xa721dfed, 0xdd732411)},
+ {TOBN(0xb4929821, 0x141d4579), TOBN(0x3411321c, 0xaa3bd435),
+ TOBN(0xafb355aa, 0x17fa6015), TOBN(0xb4e7ef4a, 0x18e42f0e)}},
+ {{TOBN(0x604ac97c, 0x59371000), TOBN(0xe1c48c70, 0x7f759c18),
+ TOBN(0x3f62ecc5, 0xa5db6b65), TOBN(0x0a78b173, 0x38a21495)},
+ {TOBN(0x6be1819d, 0xbcc8ad94), TOBN(0x70dc04f6, 0xd89c3400),
+ TOBN(0x462557b4, 0xa6b4840a), TOBN(0x544c6ade, 0x60bd21c0)}},
+ {{TOBN(0x6a00f24e, 0x907a544b), TOBN(0xa7520dcb, 0x313da210),
+ TOBN(0xfe939b75, 0x11e4994b), TOBN(0x918b6ba6, 0xbc275d70)},
+ {TOBN(0xd3e5e0fc, 0x644be892), TOBN(0x707a9816, 0xfdaf6c42),
+ TOBN(0x60145567, 0xf15c13fe), TOBN(0x4818ebaa, 0xe130a54a)}},
+ {{TOBN(0x28aad3ad, 0x58d2f767), TOBN(0xdc5267fd, 0xd7e7c773),
+ TOBN(0x4919cc88, 0xc3afcc98), TOBN(0xaa2e6ab0, 0x2db8cd4b)},
+ {TOBN(0xd46fec04, 0xd0c63eaa), TOBN(0xa1cb92c5, 0x19ffa832),
+ TOBN(0x678dd178, 0xe43a631f), TOBN(0xfb5ae1cd, 0x3dc788b3)}},
+ {{TOBN(0x68b4fb90, 0x6e77de04), TOBN(0x7992bcf0, 0xf06dbb97),
+ TOBN(0x896e6a13, 0xc417c01d), TOBN(0x8d96332c, 0xb956be01)},
+ {TOBN(0x902fc93a, 0x413aa2b9), TOBN(0x99a4d915, 0xfc98c8a5),
+ TOBN(0x52c29407, 0x565f1137), TOBN(0x4072690f, 0x21e4f281)}},
+ {{TOBN(0x36e607cf, 0x02ff6072), TOBN(0xa47d2ca9, 0x8ad98cdc),
+ TOBN(0xbf471d1e, 0xf5f56609), TOBN(0xbcf86623, 0xf264ada0)},
+ {TOBN(0xb70c0687, 0xaa9e5cb6), TOBN(0xc98124f2, 0x17401c6c),
+ TOBN(0x8189635f, 0xd4a61435), TOBN(0xd28fb8af, 0xa9d98ea6)}},
+ {{TOBN(0xb9a67c2a, 0x40c251f8), TOBN(0x88cd5d87, 0xa2da44be),
+ TOBN(0x437deb96, 0xe09b5423), TOBN(0x150467db, 0x64287dc1)},
+ {TOBN(0xe161debb, 0xcdabb839), TOBN(0xa79e9742, 0xf1839a3e),
+ TOBN(0xbb8dd3c2, 0x652d202b), TOBN(0x7b3e67f7, 0xe9f97d96)}},
+ {{TOBN(0x5aa5d78f, 0xb1cb6ac9), TOBN(0xffa13e8e, 0xca1d0d45),
+ TOBN(0x369295dd, 0x2ba5bf95), TOBN(0xd68bd1f8, 0x39aff05e)},
+ {TOBN(0xaf0d86f9, 0x26d783f2), TOBN(0x543a59b3, 0xfc3aafc1),
+ TOBN(0x3fcf81d2, 0x7b7da97c), TOBN(0xc990a056, 0xd25dee46)}},
+ {{TOBN(0x3e6775b8, 0x519cce2c), TOBN(0xfc9af71f, 0xae13d863),
+ TOBN(0x774a4a6f, 0x47c1605c), TOBN(0x46ba4245, 0x2fd205e8)},
+ {TOBN(0xa06feea4, 0xd3fd524d), TOBN(0x1e724641, 0x6de1acc2),
+ TOBN(0xf53816f1, 0x334e2b42), TOBN(0x49e5918e, 0x922f0024)}},
+ {{TOBN(0x439530b6, 0x65c7322d), TOBN(0xcf12cc01, 0xb3c1b3fb),
+ TOBN(0xc70b0186, 0x0172f685), TOBN(0xb915ee22, 0x1b58391d)},
+ {TOBN(0x9afdf03b, 0xa317db24), TOBN(0x87dec659, 0x17b8ffc4),
+ TOBN(0x7f46597b, 0xe4d3d050), TOBN(0x80a1c1ed, 0x006500e7)}},
+ {{TOBN(0x84902a96, 0x78bf030e), TOBN(0xfb5e9c9a, 0x50560148),
+ TOBN(0x6dae0a92, 0x63362426), TOBN(0xdcaeecf4, 0xa9e30c40)},
+ {TOBN(0xc0d887bb, 0x518d0c6b), TOBN(0x99181152, 0xcb985b9d),
+ TOBN(0xad186898, 0xef7bc381), TOBN(0x18168ffb, 0x9ee46201)}},
+ {{TOBN(0x9a04cdaa, 0x2502753c), TOBN(0xbb279e26, 0x51407c41),
+ TOBN(0xeacb03aa, 0xf23564e5), TOBN(0x18336582, 0x71e61016)},
+ {TOBN(0x8684b8c4, 0xeb809877), TOBN(0xb336e18d, 0xea0e672e),
+ TOBN(0xefb601f0, 0x34ee5867), TOBN(0x2733edbe, 0x1341cfd1)}},
+ {{TOBN(0xb15e809a, 0x26025c3c), TOBN(0xe6e981a6, 0x9350df88),
+ TOBN(0x92376237, 0x8502fd8e), TOBN(0x4791f216, 0x0c12be9b)},
+ {TOBN(0xb7256789, 0x25f02425), TOBN(0xec863194, 0x7a974443),
+ TOBN(0x7c0ce882, 0xfb41cc52), TOBN(0xc266ff7e, 0xf25c07f2)}},
+ {{TOBN(0x3d4da8c3, 0x017025f3), TOBN(0xefcf628c, 0xfb9579b4),
+ TOBN(0x5c4d0016, 0x1f3716ec), TOBN(0x9c27ebc4, 0x6801116e)},
+ {TOBN(0x5eba0ea1, 0x1da1767e), TOBN(0xfe151452, 0x47004c57),
+ TOBN(0x3ace6df6, 0x8c2373b7), TOBN(0x75c3dffe, 0x5dbc37ac)}},
+ {{TOBN(0x3dc32a73, 0xddc925fc), TOBN(0xb679c841, 0x2f65ee0b),
+ TOBN(0x715a3295, 0x451cbfeb), TOBN(0xd9889768, 0xf76e9a29)},
+ {TOBN(0xec20ce7f, 0xb28ad247), TOBN(0xe99146c4, 0x00894d79),
+ TOBN(0x71457d7c, 0x9f5e3ea7), TOBN(0x097b2662, 0x38030031)}},
+ {{TOBN(0xdb7f6ae6, 0xcf9f82a8), TOBN(0x319decb9, 0x438f473a),
+ TOBN(0xa63ab386, 0x283856c3), TOBN(0x13e3172f, 0xb06a361b)},
+ {TOBN(0x2959f8dc, 0x7d5a006c), TOBN(0x2dbc27c6, 0x75fba752),
+ TOBN(0xc1227ab2, 0x87c22c9e), TOBN(0x06f61f75, 0x71a268b2)}},
+ {{TOBN(0x1b6bb971, 0x04779ce2), TOBN(0xaca83812, 0x0aadcb1d),
+ TOBN(0x297ae0bc, 0xaeaab2d5), TOBN(0xa5c14ee7, 0x5bfb9f13)},
+ {TOBN(0xaa00c583, 0xf17a62c7), TOBN(0x39eb962c, 0x173759f6),
+ TOBN(0x1eeba1d4, 0x86c9a88f), TOBN(0x0ab6c37a, 0xdf016c5e)}},
+ {{TOBN(0xa2a147db, 0xa28a0749), TOBN(0x246c20d6, 0xee519165),
+ TOBN(0x5068d1b1, 0xd3810715), TOBN(0xb1e7018c, 0x748160b9)},
+ {TOBN(0x03f5b1fa, 0xf380ff62), TOBN(0xef7fb1dd, 0xf3cb2c1e),
+ TOBN(0xeab539a8, 0xfc91a7da), TOBN(0x83ddb707, 0xf3f9b561)}},
+ {{TOBN(0xc550e211, 0xfe7df7a4), TOBN(0xa7cd07f2, 0x063f6f40),
+ TOBN(0xb0de3635, 0x2976879c), TOBN(0xb5f83f85, 0xe55741da)},
+ {TOBN(0x4ea9d25e, 0xf3d8ac3d), TOBN(0x6fe2066f, 0x62819f02),
+ TOBN(0x4ab2b9c2, 0xcef4a564), TOBN(0x1e155d96, 0x5ffa2de3)}},
+ {{TOBN(0x0eb0a19b, 0xc3a72d00), TOBN(0x4037665b, 0x8513c31b),
+ TOBN(0x2fb2b6bf, 0x04c64637), TOBN(0x45c34d6e, 0x08cdc639)},
+ {TOBN(0x56f1e10f, 0xf01fd796), TOBN(0x4dfb8101, 0xfe3667b8),
+ TOBN(0xe0eda253, 0x9021d0c0), TOBN(0x7a94e9ff, 0x8a06c6ab)}},
+ {{TOBN(0x2d3bb0d9, 0xbb9aa882), TOBN(0xea20e4e5, 0xec05fd10),
+ TOBN(0xed7eeb5f, 0x1a1ca64e), TOBN(0x2fa6b43c, 0xc6327cbd)},
+ {TOBN(0xb577e3cf, 0x3aa91121), TOBN(0x8c6bd5ea, 0x3a34079b),
+ TOBN(0xd7e5ba39, 0x60e02fc0), TOBN(0xf16dd2c3, 0x90141bf8)}},
+ {{TOBN(0xb57276d9, 0x80101b98), TOBN(0x760883fd, 0xb82f0f66),
+ TOBN(0x89d7de75, 0x4bc3eff3), TOBN(0x03b60643, 0x5dc2ab40)},
+ {TOBN(0xcd6e53df, 0xe05beeac), TOBN(0xf2f1e862, 0xbc3325cd),
+ TOBN(0xdd0f7921, 0x774f03c3), TOBN(0x97ca7221, 0x4552cc1b)}},
+ {{TOBN(0x5a0d6afe, 0x1cd19f72), TOBN(0xa20915dc, 0xf183fbeb),
+ TOBN(0x9fda4b40, 0x832c403c), TOBN(0x32738edd, 0xbe425442)},
+ {TOBN(0x469a1df6, 0xb5eccf1a), TOBN(0x4b5aff42, 0x28bbe1f0),
+ TOBN(0x31359d7f, 0x570dfc93), TOBN(0xa18be235, 0xf0088628)}},
+ {{TOBN(0xa5b30fba, 0xb00ed3a9), TOBN(0x34c61374, 0x73cdf8be),
+ TOBN(0x2c5c5f46, 0xabc56797), TOBN(0x5cecf93d, 0xb82a8ae2)},
+ {TOBN(0x7d3dbe41, 0xa968fbf0), TOBN(0xd23d4583, 0x1a5c7f3d),
+ TOBN(0xf28f69a0, 0xc087a9c7), TOBN(0xc2d75471, 0x474471ca)}},
+ {{TOBN(0x36ec9f4a, 0x4eb732ec), TOBN(0x6c943bbd, 0xb1ca6bed),
+ TOBN(0xd64535e1, 0xf2457892), TOBN(0x8b84a8ea, 0xf7e2ac06)},
+ {TOBN(0xe0936cd3, 0x2499dd5f), TOBN(0x12053d7e, 0x0ed04e57),
+ TOBN(0x4bdd0076, 0xe4305d9d), TOBN(0x34a527b9, 0x1f67f0a2)}},
+ {{TOBN(0xe79a4af0, 0x9cec46ea), TOBN(0xb15347a1, 0x658b9bc7),
+ TOBN(0x6bd2796f, 0x35af2f75), TOBN(0xac957990, 0x4051c435)},
+ {TOBN(0x2669dda3, 0xc33a655d), TOBN(0x5d503c2e, 0x88514aa3),
+ TOBN(0xdfa11337, 0x3753dd41), TOBN(0x3f054673, 0x0b754f78)}},
+ {{TOBN(0xbf185677, 0x496125bd), TOBN(0xfb0023c8, 0x3775006c),
+ TOBN(0xfa0f072f, 0x3a037899), TOBN(0x4222b6eb, 0x0e4aea57)},
+ {TOBN(0x3dde5e76, 0x7866d25a), TOBN(0xb6eb04f8, 0x4837aa6f),
+ TOBN(0x5315591a, 0x2cf1cdb8), TOBN(0x6dfb4f41, 0x2d4e683c)}},
+ {{TOBN(0x7e923ea4, 0x48ee1f3a), TOBN(0x9604d9f7, 0x05a2afd5),
+ TOBN(0xbe1d4a33, 0x40ea4948), TOBN(0x5b45f1f4, 0xb44cbd2f)},
+ {TOBN(0x5faf8376, 0x4acc757e), TOBN(0xa7cf9ab8, 0x63d68ff7),
+ TOBN(0x8ad62f69, 0xdf0e404b), TOBN(0xd65f33c2, 0x12bdafdf)}},
+ {{TOBN(0xc365de15, 0xa377b14e), TOBN(0x6bf5463b, 0x8e39f60c),
+ TOBN(0x62030d2d, 0x2ce68148), TOBN(0xd95867ef, 0xe6f843a8)},
+ {TOBN(0xd39a0244, 0xef5ab017), TOBN(0x0bd2d8c1, 0x4ab55d12),
+ TOBN(0xc9503db3, 0x41639169), TOBN(0x2d4e25b0, 0xf7660c8a)}},
+ {{TOBN(0x760cb3b5, 0xe224c5d7), TOBN(0xfa3baf8c, 0x68616919),
+ TOBN(0x9fbca113, 0x8d142552), TOBN(0x1ab18bf1, 0x7669ebf5)},
+ {TOBN(0x55e6f53e, 0x9bdf25dd), TOBN(0x04cc0bf3, 0xcb6cd154),
+ TOBN(0x595bef49, 0x95e89080), TOBN(0xfe9459a8, 0x104a9ac1)}},
+ {{TOBN(0xad2d89ca, 0xcce9bb32), TOBN(0xddea65e1, 0xf7de8285),
+ TOBN(0x62ed8c35, 0xb351bd4b), TOBN(0x4150ff36, 0x0c0e19a7)},
+ {TOBN(0x86e3c801, 0x345f4e47), TOBN(0x3bf21f71, 0x203a266c),
+ TOBN(0x7ae110d4, 0x855b1f13), TOBN(0x5d6aaf6a, 0x07262517)}},
+ {{TOBN(0x1e0f12e1, 0x813d28f1), TOBN(0x6000e11d, 0x7ad7a523),
+ TOBN(0xc7d8deef, 0xc744a17b), TOBN(0x1e990b48, 0x14c05a00)},
+ {TOBN(0x68fddaee, 0x93e976d5), TOBN(0x696241d1, 0x46610d63),
+ TOBN(0xb204e7c3, 0x893dda88), TOBN(0x8bccfa65, 0x6a3a6946)}},
+ {{TOBN(0xb59425b4, 0xc5cd1411), TOBN(0x701b4042, 0xff3658b1),
+ TOBN(0xe3e56bca, 0x4784cf93), TOBN(0x27de5f15, 0x8fe68d60)},
+ {TOBN(0x4ab9cfce, 0xf8d53f19), TOBN(0xddb10311, 0xa40a730d),
+ TOBN(0x6fa73cd1, 0x4eee0a8a), TOBN(0xfd548748, 0x5249719d)}},
+ {{TOBN(0x49d66316, 0xa8123ef0), TOBN(0x73c32db4, 0xe7f95438),
+ TOBN(0x2e2ed209, 0x0d9e7854), TOBN(0xf98a9329, 0x9d9f0507)},
+ {TOBN(0xc5d33cf6, 0x0c6aa20a), TOBN(0x9a32ba14, 0x75279bb2),
+ TOBN(0x7e3202cb, 0x774a7307), TOBN(0x64ed4bc4, 0xe8c42dbd)}},
+ {{TOBN(0xc20f1a06, 0xd4caed0d), TOBN(0xb8021407, 0x171d22b3),
+ TOBN(0xd426ca04, 0xd13268d7), TOBN(0x92377007, 0x25f4d126)},
+ {TOBN(0x4204cbc3, 0x71f21a85), TOBN(0x18461b7a, 0xf82369ba),
+ TOBN(0xc0c07d31, 0x3fc858f9), TOBN(0x5deb5a50, 0xe2bab569)}},
+ {{TOBN(0xd5959d46, 0xd5eea89e), TOBN(0xfdff8424, 0x08437f4b),
+ TOBN(0xf21071e4, 0x3cfe254f), TOBN(0x72417696, 0x95468321)},
+ {TOBN(0x5d8288b9, 0x102cae3e), TOBN(0x2d143e3d, 0xf1965dff),
+ TOBN(0x00c9a376, 0xa078d847), TOBN(0x6fc0da31, 0x26028731)}},
+ {{TOBN(0xa2baeadf, 0xe45083a2), TOBN(0x66bc7218, 0x5e5b4bcd),
+ TOBN(0x2c826442, 0xd04b8e7f), TOBN(0xc19f5451, 0x6c4b586b)},
+ {TOBN(0x60182c49, 0x5b7eeed5), TOBN(0xd9954ecd, 0x7aa9dfa1),
+ TOBN(0xa403a8ec, 0xc73884ad), TOBN(0x7fb17de2, 0x9bb39041)}},
+ {{TOBN(0x694b64c5, 0xabb020e8), TOBN(0x3d18c184, 0x19c4eec7),
+ TOBN(0x9c4673ef, 0x1c4793e5), TOBN(0xc7b8aeb5, 0x056092e6)},
+ {TOBN(0x3aa1ca43, 0xf0f8c16b), TOBN(0x224ed5ec, 0xd679b2f6),
+ TOBN(0x0d56eeaf, 0x55a205c9), TOBN(0xbfe115ba, 0x4b8e028b)}},
+ {{TOBN(0x97e60849, 0x3927f4fe), TOBN(0xf91fbf94, 0x759aa7c5),
+ TOBN(0x985af769, 0x6be90a51), TOBN(0xc1277b78, 0x78ccb823)},
+ {TOBN(0x395b656e, 0xe7a75952), TOBN(0x00df7de0, 0x928da5f5),
+ TOBN(0x09c23175, 0x4ca4454f), TOBN(0x4ec971f4, 0x7aa2d3c1)}},
+ {{TOBN(0x45c3c507, 0xe75d9ccc), TOBN(0x63b7be8a, 0x3dc90306),
+ TOBN(0x37e09c66, 0x5db44bdc), TOBN(0x50d60da1, 0x6841c6a2)},
+ {TOBN(0x6f9b65ee, 0x08df1b12), TOBN(0x38734879, 0x7ff089df),
+ TOBN(0x9c331a66, 0x3fe8013d), TOBN(0x017f5de9, 0x5f42fcc8)}},
+ {{TOBN(0x43077866, 0xe8e57567), TOBN(0xc9f781ce, 0xf9fcdb18),
+ TOBN(0x38131dda, 0x9b12e174), TOBN(0x25d84aa3, 0x8a03752a)},
+ {TOBN(0x45e09e09, 0x4d0c0ce2), TOBN(0x1564008b, 0x92bebba5),
+ TOBN(0xf7e8ad31, 0xa87284c7), TOBN(0xb7c4b46c, 0x97e7bbaa)}},
+ {{TOBN(0x3e22a7b3, 0x97acf4ec), TOBN(0x0426c400, 0x5ea8b640),
+ TOBN(0x5e3295a6, 0x4e969285), TOBN(0x22aabc59, 0xa6a45670)},
+ {TOBN(0xb929714c, 0x5f5942bc), TOBN(0x9a6168bd, 0xfa3182ed),
+ TOBN(0x2216a665, 0x104152ba), TOBN(0x46908d03, 0xb6926368)}}},
+ {{{TOBN(0xa9f5d874, 0x5a1251fb), TOBN(0x967747a8, 0xc72725c7),
+ TOBN(0x195c33e5, 0x31ffe89e), TOBN(0x609d210f, 0xe964935e)},
+ {TOBN(0xcafd6ca8, 0x2fe12227), TOBN(0xaf9b5b96, 0x0426469d),
+ TOBN(0x2e9ee04c, 0x5693183c), TOBN(0x1084a333, 0xc8146fef)}},
+ {{TOBN(0x96649933, 0xaed1d1f7), TOBN(0x566eaff3, 0x50563090),
+ TOBN(0x345057f0, 0xad2e39cf), TOBN(0x148ff65b, 0x1f832124)},
+ {TOBN(0x042e89d4, 0xcf94cf0d), TOBN(0x319bec84, 0x520c58b3),
+ TOBN(0x2a267626, 0x5361aa0d), TOBN(0xc86fa302, 0x8fbc87ad)}},
+ {{TOBN(0xfc83d2ab, 0x5c8b06d5), TOBN(0xb1a785a2, 0xfe4eac46),
+ TOBN(0xb99315bc, 0x846f7779), TOBN(0xcf31d816, 0xef9ea505)},
+ {TOBN(0x2391fe6a, 0x15d7dc85), TOBN(0x2f132b04, 0xb4016b33),
+ TOBN(0x29547fe3, 0x181cb4c7), TOBN(0xdb66d8a6, 0x650155a1)}},
+ {{TOBN(0x6b66d7e1, 0xadc1696f), TOBN(0x98ebe593, 0x0acd72d0),
+ TOBN(0x65f24550, 0xcc1b7435), TOBN(0xce231393, 0xb4b9a5ec)},
+ {TOBN(0x234a22d4, 0xdb067df9), TOBN(0x98dda095, 0xcaff9b00),
+ TOBN(0x1bbc75a0, 0x6100c9c1), TOBN(0x1560a9c8, 0x939cf695)}},
+ {{TOBN(0xcf006d3e, 0x99e0925f), TOBN(0x2dd74a96, 0x6322375a),
+ TOBN(0xc58b446a, 0xb56af5ba), TOBN(0x50292683, 0xe0b9b4f1)},
+ {TOBN(0xe2c34cb4, 0x1aeaffa3), TOBN(0x8b17203f, 0x9b9587c1),
+ TOBN(0x6d559207, 0xead1350c), TOBN(0x2b66a215, 0xfb7f9604)}},
+ {{TOBN(0x0850325e, 0xfe51bf74), TOBN(0x9c4f579e, 0x5e460094),
+ TOBN(0x5c87b92a, 0x76da2f25), TOBN(0x889de4e0, 0x6febef33)},
+ {TOBN(0x6900ec06, 0x646083ce), TOBN(0xbe2a0335, 0xbfe12773),
+ TOBN(0xadd1da35, 0xc5344110), TOBN(0x757568b7, 0xb802cd20)}},
+ {{TOBN(0x75559779, 0x00f7e6c8), TOBN(0x38e8b94f, 0x0facd2f0),
+ TOBN(0xfea1f3af, 0x03fde375), TOBN(0x5e11a1d8, 0x75881dfc)},
+ {TOBN(0xb3a6b02e, 0xc1e2f2ef), TOBN(0x193d2bbb, 0xc605a6c5),
+ TOBN(0x325ffeee, 0x339a0b2d), TOBN(0x27b6a724, 0x9e0c8846)}},
+ {{TOBN(0xe4050f1c, 0xf1c367ca), TOBN(0x9bc85a9b, 0xc90fbc7d),
+ TOBN(0xa373c4a2, 0xe1a11032), TOBN(0xb64232b7, 0xad0393a9)},
+ {TOBN(0xf5577eb0, 0x167dad29), TOBN(0x1604f301, 0x94b78ab2),
+ TOBN(0x0baa94af, 0xe829348b), TOBN(0x77fbd8dd, 0x41654342)}},
+ {{TOBN(0xdab50ea5, 0xb964e39a), TOBN(0xd4c29e3c, 0xd0d3c76e),
+ TOBN(0x80dae67c, 0x56d11964), TOBN(0x7307a8bf, 0xe5ffcc2f)},
+ {TOBN(0x65bbc1aa, 0x91708c3b), TOBN(0xa151e62c, 0x28bf0eeb),
+ TOBN(0x6cb53381, 0x6fa34db7), TOBN(0x5139e05c, 0xa29403a8)}},
+ {{TOBN(0x6ff651b4, 0x94a7cd2e), TOBN(0x5671ffd1, 0x0699336c),
+ TOBN(0x6f5fd2cc, 0x979a896a), TOBN(0x11e893a8, 0xd8148cef)},
+ {TOBN(0x988906a1, 0x65cf7b10), TOBN(0x81b67178, 0xc50d8485),
+ TOBN(0x7c0deb35, 0x8a35b3de), TOBN(0x423ac855, 0xc1d29799)}},
+ {{TOBN(0xaf580d87, 0xdac50b74), TOBN(0x28b2b89f, 0x5869734c),
+ TOBN(0x99a3b936, 0x874e28fb), TOBN(0xbb2c9190, 0x25f3f73a)},
+ {TOBN(0x199f6918, 0x84a9d5b7), TOBN(0x7ebe2325, 0x7e770374),
+ TOBN(0xf442e107, 0x0738efe2), TOBN(0xcf9f3f56, 0xcf9082d2)}},
+ {{TOBN(0x719f69e1, 0x09618708), TOBN(0xcc9e8364, 0xc183f9b1),
+ TOBN(0xec203a95, 0x366a21af), TOBN(0x6aec5d6d, 0x068b141f)},
+ {TOBN(0xee2df78a, 0x994f04e9), TOBN(0xb39ccae8, 0x271245b0),
+ TOBN(0xb875a4a9, 0x97e43f4f), TOBN(0x507dfe11, 0xdb2cea98)}},
+ {{TOBN(0x4fbf81cb, 0x489b03e9), TOBN(0xdb86ec5b, 0x6ec414fa),
+ TOBN(0xfad444f9, 0xf51b3ae5), TOBN(0xca7d33d6, 0x1914e3fe)},
+ {TOBN(0xa9c32f5c, 0x0ae6c4d0), TOBN(0xa9ca1d1e, 0x73969568),
+ TOBN(0x98043c31, 0x1aa7467e), TOBN(0xe832e75c, 0xe21b5ac6)}},
+ {{TOBN(0x314b7aea, 0x5232123d), TOBN(0x08307c8c, 0x65ae86db),
+ TOBN(0x06e7165c, 0xaa4668ed), TOBN(0xb170458b, 0xb4d3ec39)},
+ {TOBN(0x4d2e3ec6, 0xc19bb986), TOBN(0xc5f34846, 0xae0304ed),
+ TOBN(0x917695a0, 0x6c9f9722), TOBN(0x6c7f7317, 0x4cab1c0a)}},
+ {{TOBN(0x6295940e, 0x9d6d2e8b), TOBN(0xd318b8c1, 0x549f7c97),
+ TOBN(0x22453204, 0x97713885), TOBN(0x468d834b, 0xa8a440fe)},
+ {TOBN(0xd81fe5b2, 0xbfba796e), TOBN(0x152364db, 0x6d71f116),
+ TOBN(0xbb8c7c59, 0xb5b66e53), TOBN(0x0b12c61b, 0x2641a192)}},
+ {{TOBN(0x31f14802, 0xfcf0a7fd), TOBN(0x42fd0789, 0x5488b01e),
+ TOBN(0x71d78d6d, 0x9952b498), TOBN(0x8eb572d9, 0x07ac5201)},
+ {TOBN(0xe0a2a44c, 0x4d194a88), TOBN(0xd2b63fd9, 0xba017e66),
+ TOBN(0x78efc6c8, 0xf888aefc), TOBN(0xb76f6bda, 0x4a881a11)}},
+ {{TOBN(0x187f314b, 0xb46c2397), TOBN(0x004cf566, 0x5ded2819),
+ TOBN(0xa9ea5704, 0x38764d34), TOBN(0xbba45217, 0x78084709)},
+ {TOBN(0x06474571, 0x1171121e), TOBN(0xad7b7eb1, 0xe7c9b671),
+ TOBN(0xdacfbc40, 0x730f7507), TOBN(0x178cd8c6, 0xc7ad7bd1)}},
+ {{TOBN(0xbf0be101, 0xb2a67238), TOBN(0x3556d367, 0xaf9c14f2),
+ TOBN(0x104b7831, 0xa5662075), TOBN(0x58ca59bb, 0x79d9e60a)},
+ {TOBN(0x4bc45392, 0xa569a73b), TOBN(0x517a52e8, 0x5698f6c9),
+ TOBN(0x85643da5, 0xaeadd755), TOBN(0x1aed0cd5, 0x2a581b84)}},
+ {{TOBN(0xb9b4ff84, 0x80af1372), TOBN(0x244c3113, 0xf1ba5d1f),
+ TOBN(0x2a5dacbe, 0xf5f98d31), TOBN(0x2c3323e8, 0x4375bc2a)},
+ {TOBN(0x17a3ab4a, 0x5594b1dd), TOBN(0xa1928bfb, 0xceb4797e),
+ TOBN(0xe83af245, 0xe4886a19), TOBN(0x8979d546, 0x72b5a74a)}},
+ {{TOBN(0xa0f726bc, 0x19f9e967), TOBN(0xd9d03152, 0xe8fbbf4e),
+ TOBN(0xcfd6f51d, 0xb7707d40), TOBN(0x633084d9, 0x63f6e6e0)},
+ {TOBN(0xedcd9cdc, 0x55667eaf), TOBN(0x73b7f92b, 0x2e44d56f),
+ TOBN(0xfb2e39b6, 0x4e962b14), TOBN(0x7d408f6e, 0xf671fcbf)}},
+ {{TOBN(0xcc634ddc, 0x164a89bb), TOBN(0x74a42bb2, 0x3ef3bd05),
+ TOBN(0x1280dbb2, 0x428decbb), TOBN(0x6103f6bb, 0x402c8596)},
+ {TOBN(0xfa2bf581, 0x355a5752), TOBN(0x562f96a8, 0x00946674),
+ TOBN(0x4e4ca16d, 0x6da0223b), TOBN(0xfe47819f, 0x28d3aa25)}},
+ {{TOBN(0x9eea3075, 0xf8dfcf8a), TOBN(0xa284f0aa, 0x95669825),
+ TOBN(0xb3fca250, 0x867d3fd8), TOBN(0x20757b5f, 0x269d691e)},
+ {TOBN(0xf2c24020, 0x93b8a5de), TOBN(0xd3f93359, 0xebc06da6),
+ TOBN(0x1178293e, 0xb2739c33), TOBN(0xd2a3e770, 0xbcd686e5)}},
+ {{TOBN(0xa76f49f4, 0xcd941534), TOBN(0x0d37406b, 0xe3c71c0e),
+ TOBN(0x172d9397, 0x3b97f7e3), TOBN(0xec17e239, 0xbd7fd0de)},
+ {TOBN(0xe3290551, 0x6f496ba2), TOBN(0x6a693172, 0x36ad50e7),
+ TOBN(0xc4e539a2, 0x83e7eff5), TOBN(0x752737e7, 0x18e1b4cf)}},
+ {{TOBN(0xa2f7932c, 0x68af43ee), TOBN(0x5502468e, 0x703d00bd),
+ TOBN(0xe5dc978f, 0x2fb061f5), TOBN(0xc9a1904a, 0x28c815ad)},
+ {TOBN(0xd3af538d, 0x470c56a4), TOBN(0x159abc5f, 0x193d8ced),
+ TOBN(0x2a37245f, 0x20108ef3), TOBN(0xfa17081e, 0x223f7178)}},
+ {{TOBN(0x27b0fb2b, 0x10c8c0f5), TOBN(0x2102c3ea, 0x40650547),
+ TOBN(0x594564df, 0x8ac3bfa7), TOBN(0x98102033, 0x509dad96)},
+ {TOBN(0x6989643f, 0xf1d18a13), TOBN(0x35eebd91, 0xd7fc5af0),
+ TOBN(0x078d096a, 0xfaeaafd8), TOBN(0xb7a89341, 0xdef3de98)}},
+ {{TOBN(0x2a206e8d, 0xecf2a73a), TOBN(0x066a6397, 0x8e551994),
+ TOBN(0x3a6a088a, 0xb98d53a2), TOBN(0x0ce7c67c, 0x2d1124aa)},
+ {TOBN(0x48cec671, 0x759a113c), TOBN(0xe3b373d3, 0x4f6f67fa),
+ TOBN(0x5455d479, 0xfd36727b), TOBN(0xe5a428ee, 0xa13c0d81)}},
+ {{TOBN(0xb853dbc8, 0x1c86682b), TOBN(0xb78d2727, 0xb8d02b2a),
+ TOBN(0xaaf69bed, 0x8ebc329a), TOBN(0xdb6b40b3, 0x293b2148)},
+ {TOBN(0xe42ea77d, 0xb8c4961f), TOBN(0xb1a12f7c, 0x20e5e0ab),
+ TOBN(0xa0ec5274, 0x79e8b05e), TOBN(0x68027391, 0xfab60a80)}},
+ {{TOBN(0x6bfeea5f, 0x16b1bd5e), TOBN(0xf957e420, 0x4de30ad3),
+ TOBN(0xcbaf664e, 0x6a353b9e), TOBN(0x5c873312, 0x26d14feb)},
+ {TOBN(0x4e87f98c, 0xb65f57cb), TOBN(0xdb60a621, 0x5e0cdd41),
+ TOBN(0x67c16865, 0xa6881440), TOBN(0x1093ef1a, 0x46ab52aa)}},
+ {{TOBN(0xc095afb5, 0x3f4ece64), TOBN(0x6a6bb02e, 0x7604551a),
+ TOBN(0x55d44b4e, 0x0b26b8cd), TOBN(0xe5f9a999, 0xf971268a)},
+ {TOBN(0xc08ec425, 0x11a7de84), TOBN(0x83568095, 0xfda469dd),
+ TOBN(0x737bfba1, 0x6c6c90a2), TOBN(0x1cb9c4a0, 0xbe229831)}},
+ {{TOBN(0x93bccbba, 0xbb2eec64), TOBN(0xa0c23b64, 0xda03adbe),
+ TOBN(0x5f7aa00a, 0xe0e86ac4), TOBN(0x470b941e, 0xfc1401e6)},
+ {TOBN(0x5ad8d679, 0x9df43574), TOBN(0x4ccfb8a9, 0x0f65d810),
+ TOBN(0x1bce80e3, 0xaa7fbd81), TOBN(0x273291ad, 0x9508d20a)}},
+ {{TOBN(0xf5c4b46b, 0x42a92806), TOBN(0x810684ec, 0xa86ab44a),
+ TOBN(0x4591640b, 0xca0bc9f8), TOBN(0xb5efcdfc, 0x5c4b6054)},
+ {TOBN(0x16fc8907, 0x6e9edd12), TOBN(0xe29d0b50, 0xd4d792f9),
+ TOBN(0xa45fd01c, 0x9b03116d), TOBN(0x85035235, 0xc81765a4)}},
+ {{TOBN(0x1fe2a9b2, 0xb4b4b67c), TOBN(0xc1d10df0, 0xe8020604),
+ TOBN(0x9d64abfc, 0xbc8058d8), TOBN(0x8943b9b2, 0x712a0fbb)},
+ {TOBN(0x90eed914, 0x3b3def04), TOBN(0x85ab3aa2, 0x4ce775ff),
+ TOBN(0x605fd4ca, 0x7bbc9040), TOBN(0x8b34a564, 0xe2c75dfb)}},
+ {{TOBN(0x41ffc94a, 0x10358560), TOBN(0x2d8a5072, 0x9e5c28aa),
+ TOBN(0xe915a0fc, 0x4cc7eb15), TOBN(0xe9efab05, 0x8f6d0f5d)},
+ {TOBN(0xdbab47a9, 0xd19e9b91), TOBN(0x8cfed745, 0x0276154c),
+ TOBN(0x154357ae, 0x2cfede0d), TOBN(0x520630df, 0x19f5a4ef)}},
+ {{TOBN(0x25759f7c, 0xe382360f), TOBN(0xb6db05c9, 0x88bf5857),
+ TOBN(0x2917d61d, 0x6c58d46c), TOBN(0x14f8e491, 0xfd20cb7a)},
+ {TOBN(0xb68a727a, 0x11c20340), TOBN(0x0386f86f, 0xaf7ccbb6),
+ TOBN(0x5c8bc6cc, 0xfee09a20), TOBN(0x7d76ff4a, 0xbb7eea35)}},
+ {{TOBN(0xa7bdebe7, 0xdb15be7a), TOBN(0x67a08054, 0xd89f0302),
+ TOBN(0x56bf0ea9, 0xc1193364), TOBN(0xc8244467, 0x62837ebe)},
+ {TOBN(0x32bd8e8b, 0x20d841b8), TOBN(0x127a0548, 0xdbb8a54f),
+ TOBN(0x83dd4ca6, 0x63b20236), TOBN(0x87714718, 0x203491fa)}},
+ {{TOBN(0x4dabcaaa, 0xaa8a5288), TOBN(0x91cc0c8a, 0xaf23a1c9),
+ TOBN(0x34c72c6a, 0x3f220e0c), TOBN(0xbcc20bdf, 0x1232144a)},
+ {TOBN(0x6e2f42da, 0xa20ede1b), TOBN(0xc441f00c, 0x74a00515),
+ TOBN(0xbf46a5b6, 0x734b8c4b), TOBN(0x57409503, 0x7b56c9a4)}},
+ {{TOBN(0x9f735261, 0xe4585d45), TOBN(0x9231faed, 0x6734e642),
+ TOBN(0x1158a176, 0xbe70ee6c), TOBN(0x35f1068d, 0x7c3501bf)},
+ {TOBN(0x6beef900, 0xa2d26115), TOBN(0x649406f2, 0xef0afee3),
+ TOBN(0x3f43a60a, 0xbc2420a1), TOBN(0x509002a7, 0xd5aee4ac)}},
+ {{TOBN(0xb46836a5, 0x3ff3571b), TOBN(0x24f98b78, 0x837927c1),
+ TOBN(0x6254256a, 0x4533c716), TOBN(0xf27abb0b, 0xd07ee196)},
+ {TOBN(0xd7cf64fc, 0x5c6d5bfd), TOBN(0x6915c751, 0xf0cd7a77),
+ TOBN(0xd9f59012, 0x8798f534), TOBN(0x772b0da8, 0xf81d8b5f)}},
+ {{TOBN(0x1244260c, 0x2e03fa69), TOBN(0x36cf0e3a, 0x3be1a374),
+ TOBN(0x6e7c1633, 0xef06b960), TOBN(0xa71a4c55, 0x671f90f6)},
+ {TOBN(0x7a941251, 0x33c673db), TOBN(0xc0bea510, 0x73e8c131),
+ TOBN(0x61a8a699, 0xd4f6c734), TOBN(0x25e78c88, 0x341ed001)}},
+ {{TOBN(0x5c18acf8, 0x8e2f7d90), TOBN(0xfdbf33d7, 0x77be32cd),
+ TOBN(0x0a085cd7, 0xd2eb5ee9), TOBN(0x2d702cfb, 0xb3201115)},
+ {TOBN(0xb6e0ebdb, 0x85c88ce8), TOBN(0x23a3ce3c, 0x1e01d617),
+ TOBN(0x3041618e, 0x567333ac), TOBN(0x9dd0fd8f, 0x157edb6b)}},
+ {{TOBN(0x27f74702, 0xb57872b8), TOBN(0x2ef26b4f, 0x657d5fe1),
+ TOBN(0x95426f0a, 0x57cf3d40), TOBN(0x847e2ad1, 0x65a6067a)},
+ {TOBN(0xd474d9a0, 0x09996a74), TOBN(0x16a56acd, 0x2a26115c),
+ TOBN(0x02a615c3, 0xd16f4d43), TOBN(0xcc3fc965, 0xaadb85b7)}},
+ {{TOBN(0x386bda73, 0xce07d1b0), TOBN(0xd82910c2, 0x58ad4178),
+ TOBN(0x124f82cf, 0xcd2617f4), TOBN(0xcc2f5e8d, 0xef691770)},
+ {TOBN(0x82702550, 0xb8c30ccc), TOBN(0x7b856aea, 0x1a8e575a),
+ TOBN(0xbb822fef, 0xb1ab9459), TOBN(0x085928bc, 0xec24e38e)}},
+ {{TOBN(0x5d0402ec, 0xba8f4b4d), TOBN(0xc07cd4ba, 0x00b4d58b),
+ TOBN(0x5d8dffd5, 0x29227e7a), TOBN(0x61d44d0c, 0x31bf386f)},
+ {TOBN(0xe486dc2b, 0x135e6f4d), TOBN(0x680962eb, 0xe79410ef),
+ TOBN(0xa61bd343, 0xf10088b5), TOBN(0x6aa76076, 0xe2e28686)}},
+ {{TOBN(0x80463d11, 0x8fb98871), TOBN(0xcb26f5c3, 0xbbc76aff),
+ TOBN(0xd4ab8edd, 0xfbe03614), TOBN(0xc8eb579b, 0xc0cf2dee)},
+ {TOBN(0xcc004c15, 0xc93bae41), TOBN(0x46fbae5d, 0x3aeca3b2),
+ TOBN(0x671235cf, 0x0f1e9ab1), TOBN(0xadfba934, 0x9ec285c1)}},
+ {{TOBN(0x88ded013, 0xf216c980), TOBN(0xc8ac4fb8, 0xf79e0bc1),
+ TOBN(0xa29b89c6, 0xfb97a237), TOBN(0xb697b780, 0x9922d8e7)},
+ {TOBN(0x3142c639, 0xddb945b5), TOBN(0x447b06c7, 0xe094c3a9),
+ TOBN(0xcdcb3642, 0x72266c90), TOBN(0x633aad08, 0xa9385046)}},
+ {{TOBN(0xa36c936b, 0xb57c6477), TOBN(0x871f8b64, 0xe94dbcc6),
+ TOBN(0x28d0fb62, 0xa591a67b), TOBN(0x9d40e081, 0xc1d926f5)},
+ {TOBN(0x3111eaf6, 0xf2d84b5a), TOBN(0x228993f9, 0xa565b644),
+ TOBN(0x0ccbf592, 0x2c83188b), TOBN(0xf87b30ab, 0x3df3e197)}},
+ {{TOBN(0xb8658b31, 0x7642bca8), TOBN(0x1a032d7f, 0x52800f17),
+ TOBN(0x051dcae5, 0x79bf9445), TOBN(0xeba6b8ee, 0x54a2e253)},
+ {TOBN(0x5c8b9cad, 0xd4485692), TOBN(0x84bda40e, 0x8986e9be),
+ TOBN(0xd16d16a4, 0x2f0db448), TOBN(0x8ec80050, 0xa14d4188)}},
+ {{TOBN(0xb2b26107, 0x98fa7aaa), TOBN(0x41209ee4, 0xf073aa4e),
+ TOBN(0xf1570359, 0xf2d6b19b), TOBN(0xcbe6868c, 0xfc577caf)},
+ {TOBN(0x186c4bdc, 0x32c04dd3), TOBN(0xa6c35fae, 0xcfeee397),
+ TOBN(0xb4a1b312, 0xf086c0cf), TOBN(0xe0a5ccc6, 0xd9461fe2)}},
+ {{TOBN(0xc32278aa, 0x1536189f), TOBN(0x1126c55f, 0xba6df571),
+ TOBN(0x0f71a602, 0xb194560e), TOBN(0x8b2d7405, 0x324bd6e1)},
+ {TOBN(0x8481939e, 0x3738be71), TOBN(0xb5090b1a, 0x1a4d97a9),
+ TOBN(0x116c65a3, 0xf05ba915), TOBN(0x21863ad3, 0xaae448aa)}},
+ {{TOBN(0xd24e2679, 0xa7aae5d3), TOBN(0x7076013d, 0x0de5c1c4),
+ TOBN(0x2d50f8ba, 0xbb05b629), TOBN(0x73c1abe2, 0x6e66efbb)},
+ {TOBN(0xefd4b422, 0xf2488af7), TOBN(0xe4105d02, 0x663ba575),
+ TOBN(0x7eb60a8b, 0x53a69457), TOBN(0x62210008, 0xc945973b)}},
+ {{TOBN(0xfb255478, 0x77a50ec6), TOBN(0xbf0392f7, 0x0a37a72c),
+ TOBN(0xa0a7a19c, 0x4be18e7a), TOBN(0x90d8ea16, 0x25b1e0af)},
+ {TOBN(0x7582a293, 0xef953f57), TOBN(0x90a64d05, 0xbdc5465a),
+ TOBN(0xca79c497, 0xe2510717), TOBN(0x560dbb7c, 0x18cb641f)}},
+ {{TOBN(0x1d8e3286, 0x4b66abfb), TOBN(0xd26f52e5, 0x59030900),
+ TOBN(0x1ee3f643, 0x5584941a), TOBN(0x6d3b3730, 0x569f5958)},
+ {TOBN(0x9ff2a62f, 0x4789dba5), TOBN(0x91fcb815, 0x72b5c9b7),
+ TOBN(0xf446cb7d, 0x6c8f9a0e), TOBN(0x48f625c1, 0x39b7ecb5)}},
+ {{TOBN(0xbabae801, 0x1c6219b8), TOBN(0xe7a562d9, 0x28ac2f23),
+ TOBN(0xe1b48732, 0x26e20588), TOBN(0x06ee1cad, 0x775af051)},
+ {TOBN(0xda29ae43, 0xfaff79f7), TOBN(0xc141a412, 0x652ee9e0),
+ TOBN(0x1e127f6f, 0x195f4bd0), TOBN(0x29c6ab4f, 0x072f34f8)}},
+ {{TOBN(0x7b7c1477, 0x30448112), TOBN(0x82b51af1, 0xe4a38656),
+ TOBN(0x2bf2028a, 0x2f315010), TOBN(0xc9a4a01f, 0x6ea88cd4)},
+ {TOBN(0xf63e95d8, 0x257e5818), TOBN(0xdd8efa10, 0xb4519b16),
+ TOBN(0xed8973e0, 0x0da910bf), TOBN(0xed49d077, 0x5c0fe4a9)}},
+ {{TOBN(0xac3aac5e, 0xb7caee1e), TOBN(0x1033898d, 0xa7f4da57),
+ TOBN(0x42145c0e, 0x5c6669b9), TOBN(0x42daa688, 0xc1aa2aa0)},
+ {TOBN(0x629cc15c, 0x1a1d885a), TOBN(0x25572ec0, 0xf4b76817),
+ TOBN(0x8312e435, 0x9c8f8f28), TOBN(0x8107f8cd, 0x81965490)}},
+ {{TOBN(0x516ff3a3, 0x6fa6110c), TOBN(0x74fb1eb1, 0xfb93561f),
+ TOBN(0x6c0c9047, 0x8457522b), TOBN(0xcfd32104, 0x6bb8bdc6)},
+ {TOBN(0x2d6884a2, 0xcc80ad57), TOBN(0x7c27fc35, 0x86a9b637),
+ TOBN(0x3461baed, 0xadf4e8cd), TOBN(0x1d56251a, 0x617242f0)}},
+ {{TOBN(0x0b80d209, 0xc955bef4), TOBN(0xdf02cad2, 0x06adb047),
+ TOBN(0xf0d7cb91, 0x5ec74fee), TOBN(0xd2503375, 0x1111ba44)},
+ {TOBN(0x9671755e, 0xdf53cb36), TOBN(0x54dcb612, 0x3368551b),
+ TOBN(0x66d69aac, 0xc8a025a4), TOBN(0x6be946c6, 0xe77ef445)}},
+ {{TOBN(0x719946d1, 0xa995e094), TOBN(0x65e848f6, 0xe51e04d8),
+ TOBN(0xe62f3300, 0x6a1e3113), TOBN(0x1541c7c1, 0x501de503)},
+ {TOBN(0x4daac9fa, 0xf4acfade), TOBN(0x0e585897, 0x44cd0b71),
+ TOBN(0x544fd869, 0x0a51cd77), TOBN(0x60fc20ed, 0x0031016d)}},
+ {{TOBN(0x58b404ec, 0xa4276867), TOBN(0x46f6c3cc, 0x34f34993),
+ TOBN(0x477ca007, 0xc636e5bd), TOBN(0x8018f5e5, 0x7c458b47)},
+ {TOBN(0xa1202270, 0xe47b668f), TOBN(0xcef48ccd, 0xee14f203),
+ TOBN(0x23f98bae, 0x62ff9b4d), TOBN(0x55acc035, 0xc589eddd)}},
+ {{TOBN(0x3fe712af, 0x64db4444), TOBN(0x19e9d634, 0xbecdd480),
+ TOBN(0xe08bc047, 0xa930978a), TOBN(0x2dbf24ec, 0xa1280733)},
+ {TOBN(0x3c0ae38c, 0x2cd706b2), TOBN(0x5b012a5b, 0x359017b9),
+ TOBN(0x3943c38c, 0x72e0f5ae), TOBN(0x786167ea, 0x57176fa3)}},
+ {{TOBN(0xe5f9897d, 0x594881dc), TOBN(0x6b5efad8, 0xcfb820c1),
+ TOBN(0xb2179093, 0xd55018de), TOBN(0x39ad7d32, 0x0bac56ce)},
+ {TOBN(0xb55122e0, 0x2cfc0e81), TOBN(0x117c4661, 0xf6d89daa),
+ TOBN(0x362d01e1, 0xcb64fa09), TOBN(0x6a309b4e, 0x3e9c4ddd)}},
+ {{TOBN(0xfa979fb7, 0xabea49b1), TOBN(0xb4b1d27d, 0x10e2c6c5),
+ TOBN(0xbd61c2c4, 0x23afde7a), TOBN(0xeb6614f8, 0x9786d358)},
+ {TOBN(0x4a5d816b, 0x7f6f7459), TOBN(0xe431a44f, 0x09360e7b),
+ TOBN(0x8c27a032, 0xc309914c), TOBN(0xcea5d68a, 0xcaede3d8)}},
+ {{TOBN(0x3668f665, 0x3a0a3f95), TOBN(0x89369416, 0x7ceba27b),
+ TOBN(0x89981fad, 0xe4728fe9), TOBN(0x7102c8a0, 0x8a093562)},
+ {TOBN(0xbb80310e, 0x235d21c8), TOBN(0x505e55d1, 0xbefb7f7b),
+ TOBN(0xa0a90811, 0x12958a67), TOBN(0xd67e106a, 0x4d851fef)}},
+ {{TOBN(0xb84011a9, 0x431dd80e), TOBN(0xeb7c7cca, 0x73306cd9),
+ TOBN(0x20fadd29, 0xd1b3b730), TOBN(0x83858b5b, 0xfe37b3d3)},
+ {TOBN(0xbf4cd193, 0xb6251d5c), TOBN(0x1cca1fd3, 0x1352d952),
+ TOBN(0xc66157a4, 0x90fbc051), TOBN(0x7990a638, 0x89b98636)}}},
+ {{{TOBN(0xe5aa692a, 0x87dec0e1), TOBN(0x010ded8d, 0xf7b39d00),
+ TOBN(0x7b1b80c8, 0x54cfa0b5), TOBN(0x66beb876, 0xa0f8ea28)},
+ {TOBN(0x50d7f531, 0x3476cd0e), TOBN(0xa63d0e65, 0xb08d3949),
+ TOBN(0x1a09eea9, 0x53479fc6), TOBN(0x82ae9891, 0xf499e742)}},
+ {{TOBN(0xab58b910, 0x5ca7d866), TOBN(0x582967e2, 0x3adb3b34),
+ TOBN(0x89ae4447, 0xcceac0bc), TOBN(0x919c667c, 0x7bf56af5)},
+ {TOBN(0x9aec17b1, 0x60f5dcd7), TOBN(0xec697b9f, 0xddcaadbc),
+ TOBN(0x0b98f341, 0x463467f5), TOBN(0xb187f1f7, 0xa967132f)}},
+ {{TOBN(0x90fe7a1d, 0x214aeb18), TOBN(0x1506af3c, 0x741432f7),
+ TOBN(0xbb5565f9, 0xe591a0c4), TOBN(0x10d41a77, 0xb44f1bc3)},
+ {TOBN(0xa09d65e4, 0xa84bde96), TOBN(0x42f060d8, 0xf20a6a1c),
+ TOBN(0x652a3bfd, 0xf27f9ce7), TOBN(0xb6bdb65c, 0x3b3d739f)}},
+ {{TOBN(0xeb5ddcb6, 0xec7fae9f), TOBN(0x995f2714, 0xefb66e5a),
+ TOBN(0xdee95d8e, 0x69445d52), TOBN(0x1b6c2d46, 0x09e27620)},
+ {TOBN(0x32621c31, 0x8129d716), TOBN(0xb03909f1, 0x0958c1aa),
+ TOBN(0x8c468ef9, 0x1af4af63), TOBN(0x162c429f, 0xfba5cdf6)}},
+ {{TOBN(0x2f682343, 0x753b9371), TOBN(0x29cab45a, 0x5f1f9cd7),
+ TOBN(0x571623ab, 0xb245db96), TOBN(0xc507db09, 0x3fd79999)},
+ {TOBN(0x4e2ef652, 0xaf036c32), TOBN(0x86f0cc78, 0x05018e5c),
+ TOBN(0xc10a73d4, 0xab8be350), TOBN(0x6519b397, 0x7e826327)}},
+ {{TOBN(0xe8cb5eef, 0x9c053df7), TOBN(0x8de25b37, 0xb300ea6f),
+ TOBN(0xdb03fa92, 0xc849cffb), TOBN(0x242e43a7, 0xe84169bb)},
+ {TOBN(0xe4fa51f4, 0xdd6f958e), TOBN(0x6925a77f, 0xf4445a8d),
+ TOBN(0xe6e72a50, 0xe90d8949), TOBN(0xc66648e3, 0x2b1f6390)}},
+ {{TOBN(0xb2ab1957, 0x173e460c), TOBN(0x1bbbce75, 0x30704590),
+ TOBN(0xc0a90dbd, 0xdb1c7162), TOBN(0x505e399e, 0x15cdd65d)},
+ {TOBN(0x68434dcb, 0x57797ab7), TOBN(0x60ad35ba, 0x6a2ca8e8),
+ TOBN(0x4bfdb1e0, 0xde3336c1), TOBN(0xbbef99eb, 0xd8b39015)}},
+ {{TOBN(0x6c3b96f3, 0x1711ebec), TOBN(0x2da40f1f, 0xce98fdc4),
+ TOBN(0xb99774d3, 0x57b4411f), TOBN(0x87c8bdf4, 0x15b65bb6)},
+ {TOBN(0xda3a89e3, 0xc2eef12d), TOBN(0xde95bb9b, 0x3c7471f3),
+ TOBN(0x600f225b, 0xd812c594), TOBN(0x54907c5d, 0x2b75a56b)}},
+ {{TOBN(0xa93cc5f0, 0x8db60e35), TOBN(0x743e3cd6, 0xfa833319),
+ TOBN(0x7dad5c41, 0xf81683c9), TOBN(0x70c1e7d9, 0x9c34107e)},
+ {TOBN(0x0edc4a39, 0xa6be0907), TOBN(0x36d47035, 0x86d0b7d3),
+ TOBN(0x8c76da03, 0x272bfa60), TOBN(0x0b4a07ea, 0x0f08a414)}},
+ {{TOBN(0x699e4d29, 0x45c1dd53), TOBN(0xcadc5898, 0x231debb5),
+ TOBN(0xdf49fcc7, 0xa77f00e0), TOBN(0x93057bbf, 0xa73e5a0e)},
+ {TOBN(0x2f8b7ecd, 0x027a4cd1), TOBN(0x114734b3, 0xc614011a),
+ TOBN(0xe7a01db7, 0x67677c68), TOBN(0x89d9be5e, 0x7e273f4f)}},
+ {{TOBN(0xd225cb2e, 0x089808ef), TOBN(0xf1f7a27d, 0xd59e4107),
+ TOBN(0x53afc761, 0x8211b9c9), TOBN(0x0361bc67, 0xe6819159)},
+ {TOBN(0x2a865d0b, 0x7f071426), TOBN(0x6a3c1810, 0xe7072567),
+ TOBN(0x3e3bca1e, 0x0d6bcabd), TOBN(0xa1b02bc1, 0x408591bc)}},
+ {{TOBN(0xe0deee59, 0x31fba239), TOBN(0xf47424d3, 0x98bd91d1),
+ TOBN(0x0f8886f4, 0x071a3c1d), TOBN(0x3f7d41e8, 0xa819233b)},
+ {TOBN(0x708623c2, 0xcf6eb998), TOBN(0x86bb49af, 0x609a287f),
+ TOBN(0x942bb249, 0x63c90762), TOBN(0x0ef6eea5, 0x55a9654b)}},
+ {{TOBN(0x5f6d2d72, 0x36f5defe), TOBN(0xfa9922dc, 0x56f99176),
+ TOBN(0x6c8c5ece, 0xf78ce0c7), TOBN(0x7b44589d, 0xbe09b55e)},
+ {TOBN(0xe11b3bca, 0x9ea83770), TOBN(0xd7fa2c7f, 0x2ab71547),
+ TOBN(0x2a3dd6fa, 0x2a1ddcc0), TOBN(0x09acb430, 0x5a7b7707)}},
+ {{TOBN(0x4add4a2e, 0x649d4e57), TOBN(0xcd53a2b0, 0x1917526e),
+ TOBN(0xc5262330, 0x20b44ac4), TOBN(0x4028746a, 0xbaa2c31d)},
+ {TOBN(0x51318390, 0x64291d4c), TOBN(0xbf48f151, 0xee5ad909),
+ TOBN(0xcce57f59, 0x7b185681), TOBN(0x7c3ac1b0, 0x4854d442)}},
+ {{TOBN(0x65587dc3, 0xc093c171), TOBN(0xae7acb24, 0x24f42b65),
+ TOBN(0x5a338adb, 0x955996cb), TOBN(0xc8e65675, 0x6051f91b)},
+ {TOBN(0x66711fba, 0x28b8d0b1), TOBN(0x15d74137, 0xb6c10a90),
+ TOBN(0x70cdd7eb, 0x3a232a80), TOBN(0xc9e2f07f, 0x6191ed24)}},
+ {{TOBN(0xa80d1db6, 0xf79588c0), TOBN(0xfa52fc69, 0xb55768cc),
+ TOBN(0x0b4df1ae, 0x7f54438a), TOBN(0x0cadd1a7, 0xf9b46a4f)},
+ {TOBN(0xb40ea6b3, 0x1803dd6f), TOBN(0x488e4fa5, 0x55eaae35),
+ TOBN(0x9f047d55, 0x382e4e16), TOBN(0xc9b5b7e0, 0x2f6e0c98)}},
+ {{TOBN(0x6b1bd2d3, 0x95762649), TOBN(0xa9604ee7, 0xc7aea3f6),
+ TOBN(0x3646ff27, 0x6dc6f896), TOBN(0x9bf0e7f5, 0x2860bad1)},
+ {TOBN(0x2d92c821, 0x7cb44b92), TOBN(0xa2f5ce63, 0xaea9c182),
+ TOBN(0xd0a2afb1, 0x9154a5fd), TOBN(0x482e474c, 0x95801da6)}},
+ {{TOBN(0xc19972d0, 0xb611c24b), TOBN(0x1d468e65, 0x60a8f351),
+ TOBN(0xeb758069, 0x7bcf6421), TOBN(0xec9dd0ee, 0x88fbc491)},
+ {TOBN(0x5b59d2bf, 0x956c2e32), TOBN(0x73dc6864, 0xdcddf94e),
+ TOBN(0xfd5e2321, 0xbcee7665), TOBN(0xa7b4f8ef, 0x5e9a06c4)}},
+ {{TOBN(0xfba918dd, 0x7280f855), TOBN(0xbbaac260, 0x8baec688),
+ TOBN(0xa3b3f00f, 0x33400f42), TOBN(0x3d2dba29, 0x66f2e6e4)},
+ {TOBN(0xb6f71a94, 0x98509375), TOBN(0x8f33031f, 0xcea423cc),
+ TOBN(0x009b8dd0, 0x4807e6fb), TOBN(0x5163cfe5, 0x5cdb954c)}},
+ {{TOBN(0x03cc8f17, 0xcf41c6e8), TOBN(0xf1f03c2a, 0x037b925c),
+ TOBN(0xc39c19cc, 0x66d2427c), TOBN(0x823d24ba, 0x7b6c18e4)},
+ {TOBN(0x32ef9013, 0x901f0b4f), TOBN(0x684360f1, 0xf8941c2e),
+ TOBN(0x0ebaff52, 0x2c28092e), TOBN(0x7891e4e3, 0x256c932f)}},
+ {{TOBN(0x51264319, 0xac445e3d), TOBN(0x553432e7, 0x8ea74381),
+ TOBN(0xe6eeaa69, 0x67e9c50a), TOBN(0x27ced284, 0x62e628c7)},
+ {TOBN(0x3f96d375, 0x7a4afa57), TOBN(0xde0a14c3, 0xe484c150),
+ TOBN(0x364a24eb, 0x38bd9923), TOBN(0x1df18da0, 0xe5177422)}},
+ {{TOBN(0x174e8f82, 0xd8d38a9b), TOBN(0x2e97c600, 0xe7de1391),
+ TOBN(0xc5709850, 0xa1c175dd), TOBN(0x969041a0, 0x32ae5035)},
+ {TOBN(0xcbfd533b, 0x76a2086b), TOBN(0xd6bba71b, 0xd7c2e8fe),
+ TOBN(0xb2d58ee6, 0x099dfb67), TOBN(0x3a8b342d, 0x064a85d9)}},
+ {{TOBN(0x3bc07649, 0x522f9be3), TOBN(0x690c075b, 0xdf1f49a8),
+ TOBN(0x80e1aee8, 0x3854ec42), TOBN(0x2a7dbf44, 0x17689dc7)},
+ {TOBN(0xc004fc0e, 0x3faf4078), TOBN(0xb2f02e9e, 0xdf11862c),
+ TOBN(0xf10a5e0f, 0xa0a1b7b3), TOBN(0x30aca623, 0x8936ec80)}},
+ {{TOBN(0xf83cbf05, 0x02f40d9a), TOBN(0x4681c468, 0x2c318a4d),
+ TOBN(0x98575618, 0x0e9c2674), TOBN(0xbe79d046, 0x1847092e)},
+ {TOBN(0xaf1e480a, 0x78bd01e0), TOBN(0x6dd359e4, 0x72a51db9),
+ TOBN(0x62ce3821, 0xe3afbab6), TOBN(0xc5cee5b6, 0x17733199)}},
+ {{TOBN(0xe08b30d4, 0x6ffd9fbb), TOBN(0x6e5bc699, 0x36c610b7),
+ TOBN(0xf343cff2, 0x9ce262cf), TOBN(0xca2e4e35, 0x68b914c1)},
+ {TOBN(0x011d64c0, 0x16de36c5), TOBN(0xe0b10fdd, 0x42e2b829),
+ TOBN(0x78942981, 0x6685aaf8), TOBN(0xe7511708, 0x230ede97)}},
+ {{TOBN(0x671ed8fc, 0x3b922bf8), TOBN(0xe4d8c0a0, 0x4c29b133),
+ TOBN(0x87eb1239, 0x3b6e99c4), TOBN(0xaff3974c, 0x8793beba)},
+ {TOBN(0x03749405, 0x2c18df9b), TOBN(0xc5c3a293, 0x91007139),
+ TOBN(0x6a77234f, 0xe37a0b95), TOBN(0x02c29a21, 0xb661c96b)}},
+ {{TOBN(0xc3aaf1d6, 0x141ecf61), TOBN(0x9195509e, 0x3bb22f53),
+ TOBN(0x29597404, 0x22d51357), TOBN(0x1b083822, 0x537bed60)},
+ {TOBN(0xcd7d6e35, 0xe07289f0), TOBN(0x1f94c48c, 0x6dd86eff),
+ TOBN(0xc8bb1f82, 0xeb0f9cfa), TOBN(0x9ee0b7e6, 0x1b2eb97d)}},
+ {{TOBN(0x5a52fe2e, 0x34d74e31), TOBN(0xa352c310, 0x3bf79ab6),
+ TOBN(0x97ff6c5a, 0xabfeeb8f), TOBN(0xbfbe8fef, 0xf5c97305)},
+ {TOBN(0xd6081ce6, 0xa7904608), TOBN(0x1f812f3a, 0xc4fca249),
+ TOBN(0x9b24bc9a, 0xb9e5e200), TOBN(0x91022c67, 0x38012ee8)}},
+ {{TOBN(0xe83d9c5d, 0x30a713a1), TOBN(0x4876e3f0, 0x84ef0f93),
+ TOBN(0xc9777029, 0xc1fbf928), TOBN(0xef7a6bb3, 0xbce7d2a4)},
+ {TOBN(0xb8067228, 0xdfa2a659), TOBN(0xd5cd3398, 0xd877a48f),
+ TOBN(0xbea4fd8f, 0x025d0f3f), TOBN(0xd67d2e35, 0x2eae7c2b)}},
+ {{TOBN(0x184de7d7, 0xcc5f4394), TOBN(0xb5551b5c, 0x4536e142),
+ TOBN(0x2e89b212, 0xd34aa60a), TOBN(0x14a96fea, 0xf50051d5)},
+ {TOBN(0x4e21ef74, 0x0d12bb0b), TOBN(0xc522f020, 0x60b9677e),
+ TOBN(0x8b12e467, 0x2df7731d), TOBN(0x39f80382, 0x7b326d31)}},
+ {{TOBN(0xdfb8630c, 0x39024a94), TOBN(0xaacb96a8, 0x97319452),
+ TOBN(0xd68a3961, 0xeda3867c), TOBN(0x0c58e2b0, 0x77c4ffca)},
+ {TOBN(0x3d545d63, 0x4da919fa), TOBN(0xef79b69a, 0xf15e2289),
+ TOBN(0x54bc3d3d, 0x808bab10), TOBN(0xc8ab3007, 0x45f82c37)}},
+ {{TOBN(0xc12738b6, 0x7c4a658a), TOBN(0xb3c47639, 0x40e72182),
+ TOBN(0x3b77be46, 0x8798e44f), TOBN(0xdc047df2, 0x17a7f85f)},
+ {TOBN(0x2439d4c5, 0x5e59d92d), TOBN(0xcedca475, 0xe8e64d8d),
+ TOBN(0xa724cd0d, 0x87ca9b16), TOBN(0x35e4fd59, 0xa5540dfe)}},
+ {{TOBN(0xf8c1ff18, 0xe4bcf6b1), TOBN(0x856d6285, 0x295018fa),
+ TOBN(0x433f665c, 0x3263c949), TOBN(0xa6a76dd6, 0xa1f21409)},
+ {TOBN(0x17d32334, 0xcc7b4f79), TOBN(0xa1d03122, 0x06720e4a),
+ TOBN(0xadb6661d, 0x81d9bed5), TOBN(0xf0d6fb02, 0x11db15d1)}},
+ {{TOBN(0x7fd11ad5, 0x1fb747d2), TOBN(0xab50f959, 0x3033762b),
+ TOBN(0x2a7e711b, 0xfbefaf5a), TOBN(0xc7393278, 0x3fef2bbf)},
+ {TOBN(0xe29fa244, 0x0df6f9be), TOBN(0x9092757b, 0x71efd215),
+ TOBN(0xee60e311, 0x4f3d6fd9), TOBN(0x338542d4, 0x0acfb78b)}},
+ {{TOBN(0x44a23f08, 0x38961a0f), TOBN(0x1426eade, 0x986987ca),
+ TOBN(0x36e6ee2e, 0x4a863cc6), TOBN(0x48059420, 0x628b8b79)},
+ {TOBN(0x30303ad8, 0x7396e1de), TOBN(0x5c8bdc48, 0x38c5aad1),
+ TOBN(0x3e40e11f, 0x5c8f5066), TOBN(0xabd6e768, 0x8d246bbd)}},
+ {{TOBN(0x68aa40bb, 0x23330a01), TOBN(0xd23f5ee4, 0xc34eafa0),
+ TOBN(0x3bbee315, 0x5de02c21), TOBN(0x18dd4397, 0xd1d8dd06)},
+ {TOBN(0x3ba1939a, 0x122d7b44), TOBN(0xe6d3b40a, 0xa33870d6),
+ TOBN(0x8e620f70, 0x1c4fe3f8), TOBN(0xf6bba1a5, 0xd3a50cbf)}},
+ {{TOBN(0x4a78bde5, 0xcfc0aee0), TOBN(0x847edc46, 0xc08c50bd),
+ TOBN(0xbaa2439c, 0xad63c9b2), TOBN(0xceb4a728, 0x10fc2acb)},
+ {TOBN(0xa419e40e, 0x26da033d), TOBN(0x6cc3889d, 0x03e02683),
+ TOBN(0x1cd28559, 0xfdccf725), TOBN(0x0fd7e0f1, 0x8d13d208)}},
+ {{TOBN(0x01b9733b, 0x1f0df9d4), TOBN(0x8cc2c5f3, 0xa2b5e4f3),
+ TOBN(0x43053bfa, 0x3a304fd4), TOBN(0x8e87665c, 0x0a9f1aa7)},
+ {TOBN(0x087f29ec, 0xd73dc965), TOBN(0x15ace455, 0x3e9023db),
+ TOBN(0x2370e309, 0x2bce28b4), TOBN(0xf9723442, 0xb6b1e84a)}},
+ {{TOBN(0xbeee662e, 0xb72d9f26), TOBN(0xb19396de, 0xf0e47109),
+ TOBN(0x85b1fa73, 0xe13289d0), TOBN(0x436cf77e, 0x54e58e32)},
+ {TOBN(0x0ec833b3, 0xe990ef77), TOBN(0x7373e3ed, 0x1b11fc25),
+ TOBN(0xbe0eda87, 0x0fc332ce), TOBN(0xced04970, 0x8d7ea856)}},
+ {{TOBN(0xf85ff785, 0x7e977ca0), TOBN(0xb66ee8da, 0xdfdd5d2b),
+ TOBN(0xf5e37950, 0x905af461), TOBN(0x587b9090, 0x966d487c)},
+ {TOBN(0x6a198a1b, 0x32ba0127), TOBN(0xa7720e07, 0x141615ac),
+ TOBN(0xa23f3499, 0x996ef2f2), TOBN(0xef5f64b4, 0x470bcb3d)}},
+ {{TOBN(0xa526a962, 0x92b8c559), TOBN(0x0c14aac0, 0x69740a0f),
+ TOBN(0x0d41a9e3, 0xa6bdc0a5), TOBN(0x97d52106, 0x9c48aef4)},
+ {TOBN(0xcf16bd30, 0x3e7c253b), TOBN(0xcc834b1a, 0x47fdedc1),
+ TOBN(0x7362c6e5, 0x373aab2e), TOBN(0x264ed85e, 0xc5f590ff)}},
+ {{TOBN(0x7a46d9c0, 0x66d41870), TOBN(0xa50c20b1, 0x4787ba09),
+ TOBN(0x185e7e51, 0xe3d44635), TOBN(0xb3b3e080, 0x31e2d8dc)},
+ {TOBN(0xbed1e558, 0xa179e9d9), TOBN(0x2daa3f79, 0x74a76781),
+ TOBN(0x4372baf2, 0x3a40864f), TOBN(0x46900c54, 0x4fe75cb5)}},
+ {{TOBN(0xb95f171e, 0xf76765d0), TOBN(0x4ad726d2, 0x95c87502),
+ TOBN(0x2ec769da, 0x4d7c99bd), TOBN(0x5e2ddd19, 0xc36cdfa8)},
+ {TOBN(0xc22117fc, 0xa93e6dea), TOBN(0xe8a2583b, 0x93771123),
+ TOBN(0xbe2f6089, 0xfa08a3a2), TOBN(0x4809d5ed, 0x8f0e1112)}},
+ {{TOBN(0x3b414aa3, 0xda7a095e), TOBN(0x9049acf1, 0x26f5aadd),
+ TOBN(0x78d46a4d, 0x6be8b84a), TOBN(0xd66b1963, 0xb732b9b3)},
+ {TOBN(0x5c2ac2a0, 0xde6e9555), TOBN(0xcf52d098, 0xb5bd8770),
+ TOBN(0x15a15fa6, 0x0fd28921), TOBN(0x56ccb81e, 0x8b27536d)}},
+ {{TOBN(0x0f0d8ab8, 0x9f4ccbb8), TOBN(0xed5f44d2, 0xdb221729),
+ TOBN(0x43141988, 0x00bed10c), TOBN(0xc94348a4, 0x1d735b8b)},
+ {TOBN(0x79f3e9c4, 0x29ef8479), TOBN(0x4c13a4e3, 0x614c693f),
+ TOBN(0x32c9af56, 0x8e143a14), TOBN(0xbc517799, 0xe29ac5c4)}},
+ {{TOBN(0x05e17992, 0x2774856f), TOBN(0x6e52fb05, 0x6c1bf55f),
+ TOBN(0xaeda4225, 0xe4f19e16), TOBN(0x70f4728a, 0xaf5ccb26)},
+ {TOBN(0x5d2118d1, 0xb2947f22), TOBN(0xc827ea16, 0x281d6fb9),
+ TOBN(0x8412328d, 0x8cf0eabd), TOBN(0x45ee9fb2, 0x03ef9dcf)}},
+ {{TOBN(0x8e700421, 0xbb937d63), TOBN(0xdf8ff2d5, 0xcc4b37a6),
+ TOBN(0xa4c0d5b2, 0x5ced7b68), TOBN(0x6537c1ef, 0xc7308f59)},
+ {TOBN(0x25ce6a26, 0x3b37f8e8), TOBN(0x170e9a9b, 0xdeebc6ce),
+ TOBN(0xdd037952, 0x8728d72c), TOBN(0x445b0e55, 0x850154bc)}},
+ {{TOBN(0x4b7d0e06, 0x83a7337b), TOBN(0x1e3416d4, 0xffecf249),
+ TOBN(0x24840eff, 0x66a2b71f), TOBN(0xd0d9a50a, 0xb37cc26d)},
+ {TOBN(0xe2198150, 0x6fe28ef7), TOBN(0x3cc5ef16, 0x23324c7f),
+ TOBN(0x220f3455, 0x769b5263), TOBN(0xe2ade2f1, 0xa10bf475)}},
+ {{TOBN(0x28cd20fa, 0x458d3671), TOBN(0x1549722c, 0x2dc4847b),
+ TOBN(0x6dd01e55, 0x591941e3), TOBN(0x0e6fbcea, 0x27128ccb)},
+ {TOBN(0xae1a1e6b, 0x3bef0262), TOBN(0xfa8c472c, 0x8f54e103),
+ TOBN(0x7539c0a8, 0x72c052ec), TOBN(0xd7b27369, 0x5a3490e9)}},
+ {{TOBN(0x143fe1f1, 0x71684349), TOBN(0x36b4722e, 0x32e19b97),
+ TOBN(0xdc059227, 0x90980aff), TOBN(0x175c9c88, 0x9e13d674)},
+ {TOBN(0xa7de5b22, 0x6e6bfdb1), TOBN(0x5ea5b7b2, 0xbedb4b46),
+ TOBN(0xd5570191, 0xd34a6e44), TOBN(0xfcf60d2e, 0xa24ff7e6)}},
+ {{TOBN(0x614a392d, 0x677819e1), TOBN(0x7be74c7e, 0xaa5a29e8),
+ TOBN(0xab50fece, 0x63c85f3f), TOBN(0xaca2e2a9, 0x46cab337)},
+ {TOBN(0x7f700388, 0x122a6fe3), TOBN(0xdb69f703, 0x882a04a8),
+ TOBN(0x9a77935d, 0xcf7aed57), TOBN(0xdf16207c, 0x8d91c86f)}},
+ {{TOBN(0x2fca49ab, 0x63ed9998), TOBN(0xa3125c44, 0xa77ddf96),
+ TOBN(0x05dd8a86, 0x24344072), TOBN(0xa023dda2, 0xfec3fb56)},
+ {TOBN(0x421b41fc, 0x0c743032), TOBN(0x4f2120c1, 0x5e438639),
+ TOBN(0xfb7cae51, 0xc83c1b07), TOBN(0xb2370caa, 0xcac2171a)}},
+ {{TOBN(0x2eb2d962, 0x6cc820fb), TOBN(0x59feee5c, 0xb85a44bf),
+ TOBN(0x94620fca, 0x5b6598f0), TOBN(0x6b922cae, 0x7e314051)},
+ {TOBN(0xff8745ad, 0x106bed4e), TOBN(0x546e71f5, 0xdfa1e9ab),
+ TOBN(0x935c1e48, 0x1ec29487), TOBN(0x9509216c, 0x4d936530)}},
+ {{TOBN(0xc7ca3067, 0x85c9a2db), TOBN(0xd6ae5152, 0x6be8606f),
+ TOBN(0x09dbcae6, 0xe14c651d), TOBN(0xc9536e23, 0x9bc32f96)},
+ {TOBN(0xa90535a9, 0x34521b03), TOBN(0xf39c526c, 0x878756ff),
+ TOBN(0x383172ec, 0x8aedf03c), TOBN(0x20a8075e, 0xefe0c034)}},
+ {{TOBN(0xf22f9c62, 0x64026422), TOBN(0x8dd10780, 0x24b9d076),
+ TOBN(0x944c742a, 0x3bef2950), TOBN(0x55b9502e, 0x88a2b00b)},
+ {TOBN(0xa59e14b4, 0x86a09817), TOBN(0xa39dd3ac, 0x47bb4071),
+ TOBN(0x55137f66, 0x3be0592f), TOBN(0x07fcafd4, 0xc9e63f5b)}},
+ {{TOBN(0x963652ee, 0x346eb226), TOBN(0x7dfab085, 0xec2facb7),
+ TOBN(0x273bf2b8, 0x691add26), TOBN(0x30d74540, 0xf2b46c44)},
+ {TOBN(0x05e8e73e, 0xf2c2d065), TOBN(0xff9b8a00, 0xd42eeac9),
+ TOBN(0x2fcbd205, 0x97209d22), TOBN(0xeb740ffa, 0xde14ea2c)}},
+ {{TOBN(0xc71ff913, 0xa8aef518), TOBN(0x7bfc74bb, 0xfff4cfa2),
+ TOBN(0x1716680c, 0xb6b36048), TOBN(0x121b2cce, 0x9ef79af1)},
+ {TOBN(0xbff3c836, 0xa01eb3d3), TOBN(0x50eb1c6a, 0x5f79077b),
+ TOBN(0xa48c32d6, 0xa004bbcf), TOBN(0x47a59316, 0x7d64f61d)}},
+ {{TOBN(0x6068147f, 0x93102016), TOBN(0x12c5f654, 0x94d12576),
+ TOBN(0xefb071a7, 0xc9bc6b91), TOBN(0x7c2da0c5, 0x6e23ea95)},
+ {TOBN(0xf4fd45b6, 0xd4a1dd5d), TOBN(0x3e7ad9b6, 0x9122b13c),
+ TOBN(0x342ca118, 0xe6f57a48), TOBN(0x1c2e94a7, 0x06f8288f)}},
+ {{TOBN(0x99e68f07, 0x5a97d231), TOBN(0x7c80de97, 0x4d838758),
+ TOBN(0xbce0f5d0, 0x05872727), TOBN(0xbe5d95c2, 0x19c4d016)},
+ {TOBN(0x921d5cb1, 0x9c2492ee), TOBN(0x42192dc1, 0x404d6fb3),
+ TOBN(0x4c84dcd1, 0x32f988d3), TOBN(0xde26d61f, 0xa17b8e85)}},
+ {{TOBN(0xc466dcb6, 0x137c7408), TOBN(0x9a38d7b6, 0x36a266da),
+ TOBN(0x7ef5cb06, 0x83bebf1b), TOBN(0xe5cdcbbf, 0x0fd014e3)},
+ {TOBN(0x30aa376d, 0xf65965a0), TOBN(0x60fe88c2, 0xebb3e95e),
+ TOBN(0x33fd0b61, 0x66ee6f20), TOBN(0x8827dcdb, 0x3f41f0a0)}},
+ {{TOBN(0xbf8a9d24, 0x0c56c690), TOBN(0x40265dad, 0xddb7641d),
+ TOBN(0x522b05bf, 0x3a6b662b), TOBN(0x466d1dfe, 0xb1478c9b)},
+ {TOBN(0xaa616962, 0x1484469b), TOBN(0x0db60549, 0x02df8f9f),
+ TOBN(0xc37bca02, 0x3cb8bf51), TOBN(0x5effe346, 0x21371ce8)}},
+ {{TOBN(0xe8f65264, 0xff112c32), TOBN(0x8a9c736d, 0x7b971fb2),
+ TOBN(0xa4f19470, 0x7b75080d), TOBN(0xfc3f2c5a, 0x8839c59b)},
+ {TOBN(0x1d6c777e, 0x5aeb49c2), TOBN(0xf3db034d, 0xda1addfe),
+ TOBN(0xd76fee5a, 0x5535affc), TOBN(0x0853ac70, 0xb92251fd)}},
+ {{TOBN(0x37e3d594, 0x8b2a29d5), TOBN(0x28f1f457, 0x4de00ddb),
+ TOBN(0x8083c1b5, 0xf42c328b), TOBN(0xd8ef1d8f, 0xe493c73b)},
+ {TOBN(0x96fb6260, 0x41dc61bd), TOBN(0xf74e8a9d, 0x27ee2f8a),
+ TOBN(0x7c605a80, 0x2c946a5d), TOBN(0xeed48d65, 0x3839ccfd)}},
+ {{TOBN(0x9894344f, 0x3a29467a), TOBN(0xde81e949, 0xc51eba6d),
+ TOBN(0xdaea066b, 0xa5e5c2f2), TOBN(0x3fc8a614, 0x08c8c7b3)},
+ {TOBN(0x7adff88f, 0x06d0de9f), TOBN(0xbbc11cf5, 0x3b75ce0a),
+ TOBN(0x9fbb7acc, 0xfbbc87d5), TOBN(0xa1458e26, 0x7badfde2)}}},
+ {{{TOBN(0x1cb43668, 0xe039c256), TOBN(0x5f26fb8b, 0x7c17fd5d),
+ TOBN(0xeee426af, 0x79aa062b), TOBN(0x072002d0, 0xd78fbf04)},
+ {TOBN(0x4c9ca237, 0xe84fb7e3), TOBN(0xb401d8a1, 0x0c82133d),
+ TOBN(0xaaa52592, 0x6d7e4181), TOBN(0xe9430833, 0x73dbb152)}},
+ {{TOBN(0xf92dda31, 0xbe24319a), TOBN(0x03f7d28b, 0xe095a8e7),
+ TOBN(0xa52fe840, 0x98782185), TOBN(0x276ddafe, 0x29c24dbc)},
+ {TOBN(0x80cd5496, 0x1d7a64eb), TOBN(0xe4360889, 0x7f1dbe42),
+ TOBN(0x2f81a877, 0x8438d2d5), TOBN(0x7e4d52a8, 0x85169036)}},
+ {{TOBN(0x19e3d5b1, 0x1d59715d), TOBN(0xc7eaa762, 0xd788983e),
+ TOBN(0xe5a730b0, 0xabf1f248), TOBN(0xfbab8084, 0xfae3fd83)},
+ {TOBN(0x65e50d21, 0x53765b2f), TOBN(0xbdd4e083, 0xfa127f3d),
+ TOBN(0x9cf3c074, 0x397b1b10), TOBN(0x59f8090c, 0xb1b59fd3)}},
+ {{TOBN(0x7b15fd9d, 0x615faa8f), TOBN(0x8fa1eb40, 0x968554ed),
+ TOBN(0x7bb4447e, 0x7aa44882), TOBN(0x2bb2d0d1, 0x029fff32)},
+ {TOBN(0x075e2a64, 0x6caa6d2f), TOBN(0x8eb879de, 0x22e7351b),
+ TOBN(0xbcd5624e, 0x9a506c62), TOBN(0x218eaef0, 0xa87e24dc)}},
+ {{TOBN(0x37e56847, 0x44ddfa35), TOBN(0x9ccfc5c5, 0xdab3f747),
+ TOBN(0x9ac1df3f, 0x1ee96cf4), TOBN(0x0c0571a1, 0x3b480b8f)},
+ {TOBN(0x2fbeb3d5, 0x4b3a7b3c), TOBN(0x35c03669, 0x5dcdbb99),
+ TOBN(0x52a0f5dc, 0xb2415b3a), TOBN(0xd57759b4, 0x4413ed9a)}},
+ {{TOBN(0x1fe647d8, 0x3d30a2c5), TOBN(0x0857f77e, 0xf78a81dc),
+ TOBN(0x11d5a334, 0x131a4a9b), TOBN(0xc0a94af9, 0x29d393f5)},
+ {TOBN(0xbc3a5c0b, 0xdaa6ec1a), TOBN(0xba9fe493, 0x88d2d7ed),
+ TOBN(0xbb4335b4, 0xbb614797), TOBN(0x991c4d68, 0x72f83533)}},
+ {{TOBN(0x53258c28, 0xd2f01cb3), TOBN(0x93d6eaa3, 0xd75db0b1),
+ TOBN(0x419a2b0d, 0xe87d0db4), TOBN(0xa1e48f03, 0xd8fe8493)},
+ {TOBN(0xf747faf6, 0xc508b23a), TOBN(0xf137571a, 0x35d53549),
+ TOBN(0x9f5e58e2, 0xfcf9b838), TOBN(0xc7186cee, 0xa7fd3cf5)}},
+ {{TOBN(0x77b868ce, 0xe978a1d3), TOBN(0xe3a68b33, 0x7ab92d04),
+ TOBN(0x51029794, 0x87a5b862), TOBN(0x5f0606c3, 0x3a61d41d)},
+ {TOBN(0x2814be27, 0x6f9326f1), TOBN(0x2f521c14, 0xc6fe3c2e),
+ TOBN(0x17464d7d, 0xacdf7351), TOBN(0x10f5f9d3, 0x777f7e44)}},
+ {{TOBN(0xce8e616b, 0x269fb37d), TOBN(0xaaf73804, 0x7de62de5),
+ TOBN(0xaba11175, 0x4fdd4153), TOBN(0x515759ba, 0x3770b49b)},
+ {TOBN(0x8b09ebf8, 0xaa423a61), TOBN(0x592245a1, 0xcd41fb92),
+ TOBN(0x1cba8ec1, 0x9b4c8936), TOBN(0xa87e91e3, 0xaf36710e)}},
+ {{TOBN(0x1fd84ce4, 0x3d34a2e3), TOBN(0xee3759ce, 0xb43b5d61),
+ TOBN(0x895bc78c, 0x619186c7), TOBN(0xf19c3809, 0xcbb9725a)},
+ {TOBN(0xc0be21aa, 0xde744b1f), TOBN(0xa7d222b0, 0x60f8056b),
+ TOBN(0x74be6157, 0xb23efe11), TOBN(0x6fab2b4f, 0x0cd68253)}},
+ {{TOBN(0xad33ea5f, 0x4bf1d725), TOBN(0x9c1d8ee2, 0x4f6c950f),
+ TOBN(0x544ee78a, 0xa377af06), TOBN(0x54f489bb, 0x94a113e1)},
+ {TOBN(0x8f11d634, 0x992fb7e8), TOBN(0x0169a7aa, 0xa2a44347),
+ TOBN(0x1d49d4af, 0x95020e00), TOBN(0x95945722, 0xe08e120b)}},
+ {{TOBN(0xb6e33878, 0xa4d32282), TOBN(0xe36e029d, 0x48020ae7),
+ TOBN(0xe05847fb, 0x37a9b750), TOBN(0xf876812c, 0xb29e3819)},
+ {TOBN(0x84ad138e, 0xd23a17f0), TOBN(0x6d7b4480, 0xf0b3950e),
+ TOBN(0xdfa8aef4, 0x2fd67ae0), TOBN(0x8d3eea24, 0x52333af6)}},
+ {{TOBN(0x0d052075, 0xb15d5acc), TOBN(0xc6d9c79f, 0xbd815bc4),
+ TOBN(0x8dcafd88, 0xdfa36cf2), TOBN(0x908ccbe2, 0x38aa9070)},
+ {TOBN(0x638722c4, 0xba35afce), TOBN(0x5a3da8b0, 0xfd6abf0b),
+ TOBN(0x2dce252c, 0xc9c335c1), TOBN(0x84e7f0de, 0x65aa799b)}},
+ {{TOBN(0x2101a522, 0xb99a72cb), TOBN(0x06de6e67, 0x87618016),
+ TOBN(0x5ff8c7cd, 0xe6f3653e), TOBN(0x0a821ab5, 0xc7a6754a)},
+ {TOBN(0x7e3fa52b, 0x7cb0b5a2), TOBN(0xa7fb121c, 0xc9048790),
+ TOBN(0x1a725020, 0x06ce053a), TOBN(0xb490a31f, 0x04e929b0)}},
+ {{TOBN(0xe17be47d, 0x62dd61ad), TOBN(0x781a961c, 0x6be01371),
+ TOBN(0x1063bfd3, 0xdae3cbba), TOBN(0x35647406, 0x7f73c9ba)},
+ {TOBN(0xf50e957b, 0x2736a129), TOBN(0xa6313702, 0xed13f256),
+ TOBN(0x9436ee65, 0x3a19fcc5), TOBN(0xcf2bdb29, 0xe7a4c8b6)}},
+ {{TOBN(0xb06b1244, 0xc5f95cd8), TOBN(0xda8c8af0, 0xf4ab95f4),
+ TOBN(0x1bae59c2, 0xb9e5836d), TOBN(0x07d51e7e, 0x3acffffc)},
+ {TOBN(0x01e15e6a, 0xc2ccbcda), TOBN(0x3bc1923f, 0x8528c3e0),
+ TOBN(0x43324577, 0xa49fead4), TOBN(0x61a1b884, 0x2aa7a711)}},
+ {{TOBN(0xf9a86e08, 0x700230ef), TOBN(0x0af585a1, 0xbd19adf8),
+ TOBN(0x7645f361, 0xf55ad8f2), TOBN(0x6e676223, 0x46c3614c)},
+ {TOBN(0x23cb257c, 0x4e774d3f), TOBN(0x82a38513, 0xac102d1b),
+ TOBN(0x9bcddd88, 0x7b126aa5), TOBN(0xe716998b, 0xeefd3ee4)}},
+ {{TOBN(0x4239d571, 0xfb167583), TOBN(0xdd011c78, 0xd16c8f8a),
+ TOBN(0x271c2895, 0x69a27519), TOBN(0x9ce0a3b7, 0xd2d64b6a)},
+ {TOBN(0x8c977289, 0xd5ec6738), TOBN(0xa3b49f9a, 0x8840ef6b),
+ TOBN(0x808c14c9, 0x9a453419), TOBN(0x5c00295b, 0x0cf0a2d5)}},
+ {{TOBN(0x524414fb, 0x1d4bcc76), TOBN(0xb07691d2, 0x459a88f1),
+ TOBN(0x77f43263, 0xf70d110f), TOBN(0x64ada5e0, 0xb7abf9f3)},
+ {TOBN(0xafd0f94e, 0x5b544cf5), TOBN(0xb4a13a15, 0xfd2713fe),
+ TOBN(0xb99b7d6e, 0x250c74f4), TOBN(0x097f2f73, 0x20324e45)}},
+ {{TOBN(0x994b37d8, 0xaffa8208), TOBN(0xc3c31b0b, 0xdc29aafc),
+ TOBN(0x3da74651, 0x7a3a607f), TOBN(0xd8e1b8c1, 0xfe6955d6)},
+ {TOBN(0x716e1815, 0xc8418682), TOBN(0x541d487f, 0x7dc91d97),
+ TOBN(0x48a04669, 0xc6996982), TOBN(0xf39cab15, 0x83a6502e)}},
+ {{TOBN(0x025801a0, 0xe68db055), TOBN(0xf3569758, 0xba3338d5),
+ TOBN(0xb0c8c0aa, 0xee2afa84), TOBN(0x4f6985d3, 0xfb6562d1)},
+ {TOBN(0x351f1f15, 0x132ed17a), TOBN(0x510ed0b4, 0xc04365fe),
+ TOBN(0xa3f98138, 0xe5b1f066), TOBN(0xbc9d95d6, 0x32df03dc)}},
+ {{TOBN(0xa83ccf6e, 0x19abd09e), TOBN(0x0b4097c1, 0x4ff17edb),
+ TOBN(0x58a5c478, 0xd64a06ce), TOBN(0x2ddcc3fd, 0x544a58fd)},
+ {TOBN(0xd449503d, 0x9e8153b8), TOBN(0x3324fd02, 0x7774179b),
+ TOBN(0xaf5d47c8, 0xdbd9120c), TOBN(0xeb860162, 0x34fa94db)}},
+ {{TOBN(0x5817bdd1, 0x972f07f4), TOBN(0xe5579e2e, 0xd27bbceb),
+ TOBN(0x86847a1f, 0x5f11e5a6), TOBN(0xb39ed255, 0x7c3cf048)},
+ {TOBN(0xe1076417, 0xa2f62e55), TOBN(0x6b9ab38f, 0x1bcf82a2),
+ TOBN(0x4bb7c319, 0x7aeb29f9), TOBN(0xf6d17da3, 0x17227a46)}},
+ {{TOBN(0xab53ddbd, 0x0f968c00), TOBN(0xa03da7ec, 0x000c880b),
+ TOBN(0x7b239624, 0x6a9ad24d), TOBN(0x612c0401, 0x01ec60d0)},
+ {TOBN(0x70d10493, 0x109f5df1), TOBN(0xfbda4030, 0x80af7550),
+ TOBN(0x30b93f95, 0xc6b9a9b3), TOBN(0x0c74ec71, 0x007d9418)}},
+ {{TOBN(0x94175564, 0x6edb951f), TOBN(0x5f4a9d78, 0x7f22c282),
+ TOBN(0xb7870895, 0xb38d1196), TOBN(0xbc593df3, 0xa228ce7c)},
+ {TOBN(0xc78c5bd4, 0x6af3641a), TOBN(0x7802200b, 0x3d9b3dcc),
+ TOBN(0x0dc73f32, 0x8be33304), TOBN(0x847ed87d, 0x61ffb79a)}},
+ {{TOBN(0xf85c974e, 0x6d671192), TOBN(0x1e14100a, 0xde16f60f),
+ TOBN(0x45cb0d5a, 0x95c38797), TOBN(0x18923bba, 0x9b022da4)},
+ {TOBN(0xef2be899, 0xbbe7e86e), TOBN(0x4a1510ee, 0x216067bf),
+ TOBN(0xd98c8154, 0x84d5ce3e), TOBN(0x1af777f0, 0xf92a2b90)}},
+ {{TOBN(0x9fbcb400, 0x4ef65724), TOBN(0x3e04a4c9, 0x3c0ca6fe),
+ TOBN(0xfb3e2cb5, 0x55002994), TOBN(0x1f3a93c5, 0x5363ecab)},
+ {TOBN(0x1fe00efe, 0x3923555b), TOBN(0x744bedd9, 0x1e1751ea),
+ TOBN(0x3fb2db59, 0x6ab69357), TOBN(0x8dbd7365, 0xf5e6618b)}},
+ {{TOBN(0x99d53099, 0xdf1ea40e), TOBN(0xb3f24a0b, 0x57d61e64),
+ TOBN(0xd088a198, 0x596eb812), TOBN(0x22c8361b, 0x5762940b)},
+ {TOBN(0x66f01f97, 0xf9c0d95c), TOBN(0x88461172, 0x8e43cdae),
+ TOBN(0x11599a7f, 0xb72b15c3), TOBN(0x135a7536, 0x420d95cc)}},
+ {{TOBN(0x2dcdf0f7, 0x5f7ae2f6), TOBN(0x15fc6e1d, 0xd7fa6da2),
+ TOBN(0x81ca829a, 0xd1d441b6), TOBN(0x84c10cf8, 0x04a106b6)},
+ {TOBN(0xa9b26c95, 0xa73fbbd0), TOBN(0x7f24e0cb, 0x4d8f6ee8),
+ TOBN(0x48b45937, 0x1e25a043), TOBN(0xf8a74fca, 0x036f3dfe)}},
+ {{TOBN(0x1ed46585, 0xc9f84296), TOBN(0x7fbaa8fb, 0x3bc278b0),
+ TOBN(0xa8e96cd4, 0x6c4fcbd0), TOBN(0x940a1202, 0x73b60a5f)},
+ {TOBN(0x34aae120, 0x55a4aec8), TOBN(0x550e9a74, 0xdbd742f0),
+ TOBN(0x794456d7, 0x228c68ab), TOBN(0x492f8868, 0xa4e25ec6)}},
+ {{TOBN(0x682915ad, 0xb2d8f398), TOBN(0xf13b51cc, 0x5b84c953),
+ TOBN(0xcda90ab8, 0x5bb917d6), TOBN(0x4b615560, 0x4ea3dee1)},
+ {TOBN(0x578b4e85, 0x0a52c1c8), TOBN(0xeab1a695, 0x20b75fc4),
+ TOBN(0x60c14f3c, 0xaa0bb3c6), TOBN(0x220f448a, 0xb8216094)}},
+ {{TOBN(0x4fe7ee31, 0xb0e63d34), TOBN(0xf4600572, 0xa9e54fab),
+ TOBN(0xc0493334, 0xd5e7b5a4), TOBN(0x8589fb92, 0x06d54831)},
+ {TOBN(0xaa70f5cc, 0x6583553a), TOBN(0x0879094a, 0xe25649e5),
+ TOBN(0xcc904507, 0x10044652), TOBN(0xebb0696d, 0x02541c4f)}},
+ {{TOBN(0x5a171fde, 0xb9718710), TOBN(0x38f1bed8, 0xf374a9f5),
+ TOBN(0xc8c582e1, 0xba39bdc1), TOBN(0xfc457b0a, 0x908cc0ce)},
+ {TOBN(0x9a187fd4, 0x883841e2), TOBN(0x8ec25b39, 0x38725381),
+ TOBN(0x2553ed05, 0x96f84395), TOBN(0x095c7661, 0x6f6c6897)}},
+ {{TOBN(0x917ac85c, 0x4bdc5610), TOBN(0xb2885fe4, 0x179eb301),
+ TOBN(0x5fc65547, 0x8b78bdcc), TOBN(0x4a9fc893, 0xe59e4699)},
+ {TOBN(0xbb7ff0cd, 0x3ce299af), TOBN(0x195be9b3, 0xadf38b20),
+ TOBN(0x6a929c87, 0xd38ddb8f), TOBN(0x55fcc99c, 0xb21a51b9)}},
+ {{TOBN(0x2b695b4c, 0x721a4593), TOBN(0xed1e9a15, 0x768eaac2),
+ TOBN(0xfb63d71c, 0x7489f914), TOBN(0xf98ba31c, 0x78118910)},
+ {TOBN(0x80291373, 0x9b128eb4), TOBN(0x7801214e, 0xd448af4a),
+ TOBN(0xdbd2e22b, 0x55418dd3), TOBN(0xeffb3c0d, 0xd3998242)}},
+ {{TOBN(0xdfa6077c, 0xc7bf3827), TOBN(0xf2165bcb, 0x47f8238f),
+ TOBN(0xfe37cf68, 0x8564d554), TOBN(0xe5f825c4, 0x0a81fb98)},
+ {TOBN(0x43cc4f67, 0xffed4d6f), TOBN(0xbc609578, 0xb50a34b0),
+ TOBN(0x8aa8fcf9, 0x5041faf1), TOBN(0x5659f053, 0x651773b6)}},
+ {{TOBN(0xe87582c3, 0x6044d63b), TOBN(0xa6089409, 0x0cdb0ca0),
+ TOBN(0x8c993e0f, 0xbfb2bcf6), TOBN(0xfc64a719, 0x45985cfc)},
+ {TOBN(0x15c4da80, 0x83dbedba), TOBN(0x804ae112, 0x2be67df7),
+ TOBN(0xda4c9658, 0xa23defde), TOBN(0x12002ddd, 0x5156e0d3)}},
+ {{TOBN(0xe68eae89, 0x5dd21b96), TOBN(0x8b99f28b, 0xcf44624d),
+ TOBN(0x0ae00808, 0x1ec8897a), TOBN(0xdd0a9303, 0x6712f76e)},
+ {TOBN(0x96237522, 0x4e233de4), TOBN(0x192445b1, 0x2b36a8a5),
+ TOBN(0xabf9ff74, 0x023993d9), TOBN(0x21f37bf4, 0x2aad4a8f)}},
+ {{TOBN(0x340a4349, 0xf8bd2bbd), TOBN(0x1d902cd9, 0x4868195d),
+ TOBN(0x3d27bbf1, 0xe5fdb6f1), TOBN(0x7a5ab088, 0x124f9f1c)},
+ {TOBN(0xc466ab06, 0xf7a09e03), TOBN(0x2f8a1977, 0x31f2c123),
+ TOBN(0xda355dc7, 0x041b6657), TOBN(0xcb840d12, 0x8ece2a7c)}},
+ {{TOBN(0xb600ad9f, 0x7db32675), TOBN(0x78fea133, 0x07a06f1b),
+ TOBN(0x5d032269, 0xb31f6094), TOBN(0x07753ef5, 0x83ec37aa)},
+ {TOBN(0x03485aed, 0x9c0bea78), TOBN(0x41bb3989, 0xbc3f4524),
+ TOBN(0x09403761, 0x697f726d), TOBN(0x6109beb3, 0xdf394820)}},
+ {{TOBN(0x804111ea, 0x3b6d1145), TOBN(0xb6271ea9, 0xa8582654),
+ TOBN(0x619615e6, 0x24e66562), TOBN(0xa2554945, 0xd7b6ad9c)},
+ {TOBN(0xd9c4985e, 0x99bfe35f), TOBN(0x9770ccc0, 0x7b51cdf6),
+ TOBN(0x7c327013, 0x92881832), TOBN(0x8777d45f, 0x286b26d1)}},
+ {{TOBN(0x9bbeda22, 0xd847999d), TOBN(0x03aa33b6, 0xc3525d32),
+ TOBN(0x4b7b96d4, 0x28a959a1), TOBN(0xbb3786e5, 0x31e5d234)},
+ {TOBN(0xaeb5d3ce, 0x6961f247), TOBN(0x20aa85af, 0x02f93d3f),
+ TOBN(0x9cd1ad3d, 0xd7a7ae4f), TOBN(0xbf6688f0, 0x781adaa8)}},
+ {{TOBN(0xb1b40e86, 0x7469cead), TOBN(0x1904c524, 0x309fca48),
+ TOBN(0x9b7312af, 0x4b54bbc7), TOBN(0xbe24bf8f, 0x593affa2)},
+ {TOBN(0xbe5e0790, 0xbd98764b), TOBN(0xa0f45f17, 0xa26e299e),
+ TOBN(0x4af0d2c2, 0x6b8fe4c7), TOBN(0xef170db1, 0x8ae8a3e6)}},
+ {{TOBN(0x0e8d61a0, 0x29e0ccc1), TOBN(0xcd53e87e, 0x60ad36ca),
+ TOBN(0x328c6623, 0xc8173822), TOBN(0x7ee1767d, 0xa496be55)},
+ {TOBN(0x89f13259, 0x648945af), TOBN(0x9e45a5fd, 0x25c8009c),
+ TOBN(0xaf2febd9, 0x1f61ab8c), TOBN(0x43f6bc86, 0x8a275385)}},
+ {{TOBN(0x87792348, 0xf2142e79), TOBN(0x17d89259, 0xc6e6238a),
+ TOBN(0x7536d2f6, 0x4a839d9b), TOBN(0x1f428fce, 0x76a1fbdc)},
+ {TOBN(0x1c109601, 0x0db06dfe), TOBN(0xbfc16bc1, 0x50a3a3cc),
+ TOBN(0xf9cbd9ec, 0x9b30f41b), TOBN(0x5b5da0d6, 0x00138cce)}},
+ {{TOBN(0xec1d0a48, 0x56ef96a7), TOBN(0xb47eb848, 0x982bf842),
+ TOBN(0x66deae32, 0xec3f700d), TOBN(0x4e43c42c, 0xaa1181e0)},
+ {TOBN(0xa1d72a31, 0xd1a4aa2a), TOBN(0x440d4668, 0xc004f3ce),
+ TOBN(0x0d6a2d3b, 0x45fe8a7a), TOBN(0x820e52e2, 0xfb128365)}},
+ {{TOBN(0x29ac5fcf, 0x25e51b09), TOBN(0x180cd2bf, 0x2023d159),
+ TOBN(0xa9892171, 0xa1ebf90e), TOBN(0xf97c4c87, 0x7c132181)},
+ {TOBN(0x9f1dc724, 0xc03dbb7e), TOBN(0xae043765, 0x018cbbe4),
+ TOBN(0xfb0b2a36, 0x0767d153), TOBN(0xa8e2f4d6, 0x249cbaeb)}},
+ {{TOBN(0x172a5247, 0xd95ea168), TOBN(0x1758fada, 0x2970764a),
+ TOBN(0xac803a51, 0x1d978169), TOBN(0x299cfe2e, 0xde77e01b)},
+ {TOBN(0x652a1e17, 0xb0a98927), TOBN(0x2e26e1d1, 0x20014495),
+ TOBN(0x7ae0af9f, 0x7175b56a), TOBN(0xc2e22a80, 0xd64b9f95)}},
+ {{TOBN(0x4d0ff9fb, 0xd90a060a), TOBN(0x496a27db, 0xbaf38085),
+ TOBN(0x32305401, 0xda776bcf), TOBN(0xb8cdcef6, 0x725f209e)},
+ {TOBN(0x61ba0f37, 0x436a0bba), TOBN(0x263fa108, 0x76860049),
+ TOBN(0x92beb98e, 0xda3542cf), TOBN(0xa2d4d14a, 0xd5849538)}},
+ {{TOBN(0x989b9d68, 0x12e9a1bc), TOBN(0x61d9075c, 0x5f6e3268),
+ TOBN(0x352c6aa9, 0x99ace638), TOBN(0xde4e4a55, 0x920f43ff)},
+ {TOBN(0xe5e4144a, 0xd673c017), TOBN(0x667417ae, 0x6f6e05ea),
+ TOBN(0x613416ae, 0xdcd1bd56), TOBN(0x5eb36201, 0x86693711)}},
+ {{TOBN(0x2d7bc504, 0x3a1aa914), TOBN(0x175a1299, 0x76dc5975),
+ TOBN(0xe900e0f2, 0x3fc8125c), TOBN(0x569ef68c, 0x11198875)},
+ {TOBN(0x9012db63, 0x63a113b4), TOBN(0xe3bd3f56, 0x98835766),
+ TOBN(0xa5c94a52, 0x76412dea), TOBN(0xad9e2a09, 0xaa735e5c)}},
+ {{TOBN(0x405a984c, 0x508b65e9), TOBN(0xbde4a1d1, 0x6df1a0d1),
+ TOBN(0x1a9433a1, 0xdfba80da), TOBN(0xe9192ff9, 0x9440ad2e)},
+ {TOBN(0x9f649696, 0x5099fe92), TOBN(0x25ddb65c, 0x0b27a54a),
+ TOBN(0x178279dd, 0xc590da61), TOBN(0x5479a999, 0xfbde681a)}},
+ {{TOBN(0xd0e84e05, 0x013fe162), TOBN(0xbe11dc92, 0x632d471b),
+ TOBN(0xdf0b0c45, 0xfc0e089f), TOBN(0x04fb15b0, 0x4c144025)},
+ {TOBN(0xa61d5fc2, 0x13c99927), TOBN(0xa033e9e0, 0x3de2eb35),
+ TOBN(0xf8185d5c, 0xb8dacbb4), TOBN(0x9a88e265, 0x8644549d)}},
+ {{TOBN(0xf717af62, 0x54671ff6), TOBN(0x4bd4241b, 0x5fa58603),
+ TOBN(0x06fba40b, 0xe67773c0), TOBN(0xc1d933d2, 0x6a2847e9)},
+ {TOBN(0xf4f5acf3, 0x689e2c70), TOBN(0x92aab0e7, 0x46bafd31),
+ TOBN(0x798d76aa, 0x3473f6e5), TOBN(0xcc6641db, 0x93141934)}},
+ {{TOBN(0xcae27757, 0xd31e535e), TOBN(0x04cc43b6, 0x87c2ee11),
+ TOBN(0x8d1f9675, 0x2e029ffa), TOBN(0xc2150672, 0xe4cc7a2c)},
+ {TOBN(0x3b03c1e0, 0x8d68b013), TOBN(0xa9d6816f, 0xedf298f3),
+ TOBN(0x1bfbb529, 0xa2804464), TOBN(0x95a52fae, 0x5db22125)}},
+ {{TOBN(0x55b32160, 0x0e1cb64e), TOBN(0x004828f6, 0x7e7fc9fe),
+ TOBN(0x13394b82, 0x1bb0fb93), TOBN(0xb6293a2d, 0x35f1a920)},
+ {TOBN(0xde35ef21, 0xd145d2d9), TOBN(0xbe6225b3, 0xbb8fa603),
+ TOBN(0x00fc8f6b, 0x32cf252d), TOBN(0xa28e52e6, 0x117cf8c2)}},
+ {{TOBN(0x9d1dc89b, 0x4c371e6d), TOBN(0xcebe0675, 0x36ef0f28),
+ TOBN(0x5de05d09, 0xa4292f81), TOBN(0xa8303593, 0x353e3083)},
+ {TOBN(0xa1715b0a, 0x7e37a9bb), TOBN(0x8c56f61e, 0x2b8faec3),
+ TOBN(0x52507431, 0x33c9b102), TOBN(0x0130cefc, 0xa44431f0)}},
+ {{TOBN(0x56039fa0, 0xbd865cfb), TOBN(0x4b03e578, 0xbc5f1dd7),
+ TOBN(0x40edf2e4, 0xbabe7224), TOBN(0xc752496d, 0x3a1988f6)},
+ {TOBN(0xd1572d3b, 0x564beb6b), TOBN(0x0db1d110, 0x39a1c608),
+ TOBN(0x568d1934, 0x16f60126), TOBN(0x05ae9668, 0xf354af33)}},
+ {{TOBN(0x19de6d37, 0xc92544f2), TOBN(0xcc084353, 0xa35837d5),
+ TOBN(0xcbb6869c, 0x1a514ece), TOBN(0xb633e728, 0x2e1d1066)},
+ {TOBN(0xf15dd69f, 0x936c581c), TOBN(0x96e7b8ce, 0x7439c4f9),
+ TOBN(0x5e676f48, 0x2e448a5b), TOBN(0xb2ca7d5b, 0xfd916bbb)}},
+ {{TOBN(0xd55a2541, 0xf5024025), TOBN(0x47bc5769, 0xe4c2d937),
+ TOBN(0x7d31b92a, 0x0362189f), TOBN(0x83f3086e, 0xef7816f9)},
+ {TOBN(0xf9f46d94, 0xb587579a), TOBN(0xec2d22d8, 0x30e76c5f),
+ TOBN(0x27d57461, 0xb000ffcf), TOBN(0xbb7e65f9, 0x364ffc2c)}},
+ {{TOBN(0x7c7c9477, 0x6652a220), TOBN(0x61618f89, 0xd696c981),
+ TOBN(0x5021701d, 0x89effff3), TOBN(0xf2c8ff8e, 0x7c314163)},
+ {TOBN(0x2da413ad, 0x8efb4d3e), TOBN(0x937b5adf, 0xce176d95),
+ TOBN(0x22867d34, 0x2a67d51c), TOBN(0x262b9b10, 0x18eb3ac9)}},
+ {{TOBN(0x4e314fe4, 0xc43ff28b), TOBN(0x76476627, 0x6a664e7a),
+ TOBN(0x3e90e40b, 0xb7a565c2), TOBN(0x8588993a, 0xc1acf831)},
+ {TOBN(0xd7b501d6, 0x8f938829), TOBN(0x996627ee, 0x3edd7d4c),
+ TOBN(0x37d44a62, 0x90cd34c7), TOBN(0xa8327499, 0xf3833e8d)}},
+ {{TOBN(0x2e18917d, 0x4bf50353), TOBN(0x85dd726b, 0x556765fb),
+ TOBN(0x54fe65d6, 0x93d5ab66), TOBN(0x3ddbaced, 0x915c25fe)},
+ {TOBN(0xa799d9a4, 0x12f22e85), TOBN(0xe2a24867, 0x6d06f6bc),
+ TOBN(0xf4f1ee56, 0x43ca1637), TOBN(0xfda2828b, 0x61ece30a)}},
+ {{TOBN(0x758c1a3e, 0xa2dee7a6), TOBN(0xdcde2f3c, 0x734b2284),
+ TOBN(0xaba445d2, 0x4eaba6ad), TOBN(0x35aaf668, 0x76cee0a7)},
+ {TOBN(0x7e0b04a9, 0xe5aa049a), TOBN(0xe74083ad, 0x91103e84),
+ TOBN(0xbeb183ce, 0x40afecc3), TOBN(0x6b89de9f, 0xea043f7a)}}},
+ {{{TOBN(0x0e299d23, 0xfe67ba66), TOBN(0x91450760, 0x93cf2f34),
+ TOBN(0xf45b5ea9, 0x97fcf913), TOBN(0x5be00843, 0x8bd7ddda)},
+ {TOBN(0x358c3e05, 0xd53ff04d), TOBN(0xbf7ccdc3, 0x5de91ef7),
+ TOBN(0xad684dbf, 0xb69ec1a0), TOBN(0x367e7cf2, 0x801fd997)}},
+ {{TOBN(0x0ca1f3b7, 0xb0dc8595), TOBN(0x27de4608, 0x9f1d9f2e),
+ TOBN(0x1af3bf39, 0xbadd82a7), TOBN(0x79356a79, 0x65862448)},
+ {TOBN(0xc0602345, 0xf5f9a052), TOBN(0x1a8b0f89, 0x139a42f9),
+ TOBN(0xb53eee42, 0x844d40fc), TOBN(0x93b0bfe5, 0x4e5b6368)}},
+ {{TOBN(0x5434dd02, 0xc024789c), TOBN(0x90dca9ea, 0x41b57bfc),
+ TOBN(0x8aa898e2, 0x243398df), TOBN(0xf607c834, 0x894a94bb)},
+ {TOBN(0xbb07be97, 0xc2c99b76), TOBN(0x6576ba67, 0x18c29302),
+ TOBN(0x3d79efcc, 0xe703a88c), TOBN(0xf259ced7, 0xb6a0d106)}},
+ {{TOBN(0x0f893a5d, 0xc8de610b), TOBN(0xe8c515fb, 0x67e223ce),
+ TOBN(0x7774bfa6, 0x4ead6dc5), TOBN(0x89d20f95, 0x925c728f)},
+ {TOBN(0x7a1e0966, 0x098583ce), TOBN(0xa2eedb94, 0x93f2a7d7),
+ TOBN(0x1b282097, 0x4c304d4a), TOBN(0x0842e3da, 0xc077282d)}},
+ {{TOBN(0xe4d972a3, 0x3b9e2d7b), TOBN(0x7cc60b27, 0xc48218ff),
+ TOBN(0x8fc70838, 0x84149d91), TOBN(0x5c04346f, 0x2f461ecc)},
+ {TOBN(0xebe9fdf2, 0x614650a9), TOBN(0x5e35b537, 0xc1f666ac),
+ TOBN(0x645613d1, 0x88babc83), TOBN(0x88cace3a, 0xc5e1c93e)}},
+ {{TOBN(0x209ca375, 0x3de92e23), TOBN(0xccb03cc8, 0x5fbbb6e3),
+ TOBN(0xccb90f03, 0xd7b1487e), TOBN(0xfa9c2a38, 0xc710941f)},
+ {TOBN(0x756c3823, 0x6724ceed), TOBN(0x3a902258, 0x192d0323),
+ TOBN(0xb150e519, 0xea5e038e), TOBN(0xdcba2865, 0xc7427591)}},
+ {{TOBN(0xe549237f, 0x78890732), TOBN(0xc443bef9, 0x53fcb4d9),
+ TOBN(0x9884d8a6, 0xeb3480d6), TOBN(0x8a35b6a1, 0x3048b186)},
+ {TOBN(0xb4e44716, 0x65e9a90a), TOBN(0x45bf380d, 0x653006c0),
+ TOBN(0x8f3f820d, 0x4fe9ae3b), TOBN(0x244a35a0, 0x979a3b71)}},
+ {{TOBN(0xa1010e9d, 0x74cd06ff), TOBN(0x9c17c7df, 0xaca3eeac),
+ TOBN(0x74c86cd3, 0x8063aa2b), TOBN(0x8595c4b3, 0x734614ff)},
+ {TOBN(0xa3de00ca, 0x990f62cc), TOBN(0xd9bed213, 0xca0c3be5),
+ TOBN(0x7886078a, 0xdf8ce9f5), TOBN(0xddb27ce3, 0x5cd44444)}},
+ {{TOBN(0xed374a66, 0x58926ddd), TOBN(0x138b2d49, 0x908015b8),
+ TOBN(0x886c6579, 0xde1f7ab8), TOBN(0x888b9aa0, 0xc3020b7a)},
+ {TOBN(0xd3ec034e, 0x3a96e355), TOBN(0xba65b0b8, 0xf30fbe9a),
+ TOBN(0x064c8e50, 0xff21367a), TOBN(0x1f508ea4, 0x0b04b46e)}},
+ {{TOBN(0x98561a49, 0x747c866c), TOBN(0xbbb1e5fe, 0x0518a062),
+ TOBN(0x20ff4e8b, 0xecdc3608), TOBN(0x7f55cded, 0x20184027)},
+ {TOBN(0x8d73ec95, 0xf38c85f0), TOBN(0x5b589fdf, 0x8bc3b8c3),
+ TOBN(0xbe95dd98, 0x0f12b66f), TOBN(0xf5bd1a09, 0x0e338e01)}},
+ {{TOBN(0x65163ae5, 0x5e915918), TOBN(0x6158d6d9, 0x86f8a46b),
+ TOBN(0x8466b538, 0xeeebf99c), TOBN(0xca8761f6, 0xbca477ef)},
+ {TOBN(0xaf3449c2, 0x9ebbc601), TOBN(0xef3b0f41, 0xe0c3ae2f),
+ TOBN(0xaa6c577d, 0x5de63752), TOBN(0xe9166601, 0x64682a51)}},
+ {{TOBN(0x5a3097be, 0xfc15aa1e), TOBN(0x40d12548, 0xb54b0745),
+ TOBN(0x5bad4706, 0x519a5f12), TOBN(0xed03f717, 0xa439dee6)},
+ {TOBN(0x0794bb6c, 0x4a02c499), TOBN(0xf725083d, 0xcffe71d2),
+ TOBN(0x2cad7519, 0x0f3adcaf), TOBN(0x7f68ea1c, 0x43729310)}},
+ {{TOBN(0xe747c8c7, 0xb7ffd977), TOBN(0xec104c35, 0x80761a22),
+ TOBN(0x8395ebaf, 0x5a3ffb83), TOBN(0xfb3261f4, 0xe4b63db7)},
+ {TOBN(0x53544960, 0xd883e544), TOBN(0x13520d70, 0x8cc2eeb8),
+ TOBN(0x08f6337b, 0xd3d65f99), TOBN(0x83997db2, 0x781cf95b)}},
+ {{TOBN(0xce6ff106, 0x0dbd2c01), TOBN(0x4f8eea6b, 0x1f9ce934),
+ TOBN(0x546f7c4b, 0x0e993921), TOBN(0x6236a324, 0x5e753fc7)},
+ {TOBN(0x65a41f84, 0xa16022e9), TOBN(0x0c18d878, 0x43d1dbb2),
+ TOBN(0x73c55640, 0x2d4cef9c), TOBN(0xa0428108, 0x70444c74)}},
+ {{TOBN(0x68e4f15e, 0x9afdfb3c), TOBN(0x49a56143, 0x5bdfb6df),
+ TOBN(0xa9bc1bd4, 0x5f823d97), TOBN(0xbceb5970, 0xea111c2a)},
+ {TOBN(0x366b455f, 0xb269bbc4), TOBN(0x7cd85e1e, 0xe9bc5d62),
+ TOBN(0xc743c41c, 0x4f18b086), TOBN(0xa4b40990, 0x95294fb9)}},
+ {{TOBN(0x9c7c581d, 0x26ee8382), TOBN(0xcf17dcc5, 0x359d638e),
+ TOBN(0xee8273ab, 0xb728ae3d), TOBN(0x1d112926, 0xf821f047)},
+ {TOBN(0x11498477, 0x50491a74), TOBN(0x687fa761, 0xfde0dfb9),
+ TOBN(0x2c258022, 0x7ea435ab), TOBN(0x6b8bdb94, 0x91ce7e3f)}},
+ {{TOBN(0x4c5b5dc9, 0x3bf834aa), TOBN(0x04371819, 0x4f6c7e4b),
+ TOBN(0xc284e00a, 0x3736bcad), TOBN(0x0d881118, 0x21ae8f8d)},
+ {TOBN(0xf9cf0f82, 0xf48c8e33), TOBN(0xa11fd075, 0xa1bf40db),
+ TOBN(0xdceab0de, 0xdc2733e5), TOBN(0xc560a8b5, 0x8e986bd7)}},
+ {{TOBN(0x48dd1fe2, 0x3929d097), TOBN(0x3885b290, 0x92f188f1),
+ TOBN(0x0f2ae613, 0xda6fcdac), TOBN(0x9054303e, 0xb662a46c)},
+ {TOBN(0xb6871e44, 0x0738042a), TOBN(0x98e6a977, 0xbdaf6449),
+ TOBN(0xd8bc0650, 0xd1c9df1b), TOBN(0xef3d6451, 0x36e098f9)}},
+ {{TOBN(0x03fbae82, 0xb6d72d28), TOBN(0x77ca9db1, 0xf5d84080),
+ TOBN(0x8a112cff, 0xa58efc1c), TOBN(0x518d761c, 0xc564cb4a)},
+ {TOBN(0x69b5740e, 0xf0d1b5ce), TOBN(0x717039cc, 0xe9eb1785),
+ TOBN(0x3fe29f90, 0x22f53382), TOBN(0x8e54ba56, 0x6bc7c95c)}},
+ {{TOBN(0x9c806d8a, 0xf7f91d0f), TOBN(0x3b61b0f1, 0xa82a5728),
+ TOBN(0x4640032d, 0x94d76754), TOBN(0x273eb5de, 0x47d834c6)},
+ {TOBN(0x2988abf7, 0x7b4e4d53), TOBN(0xb7ce66bf, 0xde401777),
+ TOBN(0x9fba6b32, 0x715071b3), TOBN(0x82413c24, 0xad3a1a98)}},
+ {{TOBN(0x5b7fc8c4, 0xe0e8ad93), TOBN(0xb5679aee, 0x5fab868d),
+ TOBN(0xb1f9d2fa, 0x2b3946f3), TOBN(0x458897dc, 0x5685b50a)},
+ {TOBN(0x1e98c930, 0x89d0caf3), TOBN(0x39564c5f, 0x78642e92),
+ TOBN(0x1b77729a, 0x0dbdaf18), TOBN(0xf9170722, 0x579e82e6)}},
+ {{TOBN(0x680c0317, 0xe4515fa5), TOBN(0xf85cff84, 0xfb0c790f),
+ TOBN(0xc7a82aab, 0x6d2e0765), TOBN(0x7446bca9, 0x35c82b32)},
+ {TOBN(0x5de607aa, 0x6d63184f), TOBN(0x7c1a46a8, 0x262803a6),
+ TOBN(0xd218313d, 0xaebe8035), TOBN(0x92113ffd, 0xc73c51f8)}},
+ {{TOBN(0x4b38e083, 0x12e7e46c), TOBN(0x69d0a37a, 0x56126bd5),
+ TOBN(0xfb3f324b, 0x73c07e04), TOBN(0xa0c22f67, 0x8fda7267)},
+ {TOBN(0x8f2c0051, 0x4d2c7d8f), TOBN(0xbc45ced3, 0xcbe2cae5),
+ TOBN(0xe1c6cf07, 0xa8f0f277), TOBN(0xbc392312, 0x1eb99a98)}},
+ {{TOBN(0x75537b7e, 0x3cc8ac85), TOBN(0x8d725f57, 0xdd02753b),
+ TOBN(0xfd05ff64, 0xb737df2f), TOBN(0x55fe8712, 0xf6d2531d)},
+ {TOBN(0x57ce04a9, 0x6ab6b01c), TOBN(0x69a02a89, 0x7cd93724),
+ TOBN(0x4f82ac35, 0xcf86699b), TOBN(0x8242d3ad, 0x9cb4b232)}},
+ {{TOBN(0x713d0f65, 0xd62105e5), TOBN(0xbb222bfa, 0x2d29be61),
+ TOBN(0xf2f9a79e, 0x6cfbef09), TOBN(0xfc24d8d3, 0xd5d6782f)},
+ {TOBN(0x5db77085, 0xd4129967), TOBN(0xdb81c3cc, 0xdc3c2a43),
+ TOBN(0x9d655fc0, 0x05d8d9a3), TOBN(0x3f5d057a, 0x54298026)}},
+ {{TOBN(0x1157f56d, 0x88c54694), TOBN(0xb26baba5, 0x9b09573e),
+ TOBN(0x2cab03b0, 0x22adffd1), TOBN(0x60a412c8, 0xdd69f383)},
+ {TOBN(0xed76e98b, 0x54b25039), TOBN(0xd4ee67d3, 0x687e714d),
+ TOBN(0x87739648, 0x7b00b594), TOBN(0xce419775, 0xc9ef709b)}},
+ {{TOBN(0x40f76f85, 0x1c203a40), TOBN(0x30d352d6, 0xeafd8f91),
+ TOBN(0xaf196d3d, 0x95578dd2), TOBN(0xea4bb3d7, 0x77cc3f3d)},
+ {TOBN(0x42a5bd03, 0xb98e782b), TOBN(0xac958c40, 0x0624920d),
+ TOBN(0xb838134c, 0xfc56fcc8), TOBN(0x86ec4ccf, 0x89572e5e)}},
+ {{TOBN(0x69c43526, 0x9be47be0), TOBN(0x323b7dd8, 0xcb28fea1),
+ TOBN(0xfa5538ba, 0x3a6c67e5), TOBN(0xef921d70, 0x1d378e46)},
+ {TOBN(0xf92961fc, 0x3c4b880e), TOBN(0x3f6f914e, 0x98940a67),
+ TOBN(0xa990eb0a, 0xfef0ff39), TOBN(0xa6c2920f, 0xf0eeff9c)}},
+ {{TOBN(0xca804166, 0x51b8d9a3), TOBN(0x42531bc9, 0x0ffb0db1),
+ TOBN(0x72ce4718, 0xaa82e7ce), TOBN(0x6e199913, 0xdf574741)},
+ {TOBN(0xd5f1b13d, 0xd5d36946), TOBN(0x8255dc65, 0xf68f0194),
+ TOBN(0xdc9df4cd, 0x8710d230), TOBN(0x3453c20f, 0x138c1988)}},
+ {{TOBN(0x9af98dc0, 0x89a6ef01), TOBN(0x4dbcc3f0, 0x9857df85),
+ TOBN(0x34805601, 0x5c1ad924), TOBN(0x40448da5, 0xd0493046)},
+ {TOBN(0xf629926d, 0x4ee343e2), TOBN(0x6343f1bd, 0x90e8a301),
+ TOBN(0xefc93491, 0x40815b3f), TOBN(0xf882a423, 0xde8f66fb)}},
+ {{TOBN(0x3a12d5f4, 0xe7db9f57), TOBN(0x7dfba38a, 0x3c384c27),
+ TOBN(0x7a904bfd, 0x6fc660b1), TOBN(0xeb6c5db3, 0x2773b21c)},
+ {TOBN(0xc350ee66, 0x1cdfe049), TOBN(0x9baac0ce, 0x44540f29),
+ TOBN(0xbc57b6ab, 0xa5ec6aad), TOBN(0x167ce8c3, 0x0a7c1baa)}},
+ {{TOBN(0xb23a03a5, 0x53fb2b56), TOBN(0x6ce141e7, 0x4e057f78),
+ TOBN(0x796525c3, 0x89e490d9), TOBN(0x0bc95725, 0xa31a7e75)},
+ {TOBN(0x1ec56791, 0x1220fd06), TOBN(0x716e3a3c, 0x408b0bd6),
+ TOBN(0x31cd6bf7, 0xe8ebeba9), TOBN(0xa7326ca6, 0xbee6b670)}},
+ {{TOBN(0x3d9f851c, 0xcd090c43), TOBN(0x561e8f13, 0xf12c3988),
+ TOBN(0x50490b6a, 0x904b7be4), TOBN(0x61690ce1, 0x0410737b)},
+ {TOBN(0x299e9a37, 0x0f009052), TOBN(0x258758f0, 0xf026092e),
+ TOBN(0x9fa255f3, 0xfdfcdc0f), TOBN(0xdbc9fb1f, 0xc0e1bcd2)}},
+ {{TOBN(0x35f9dd6e, 0x24651840), TOBN(0xdca45a84, 0xa5c59abc),
+ TOBN(0x103d396f, 0xecca4938), TOBN(0x4532da0a, 0xb97b3f29)},
+ {TOBN(0xc4135ea5, 0x1999a6bf), TOBN(0x3aa9505a, 0x5e6bf2ee),
+ TOBN(0xf77cef06, 0x3f5be093), TOBN(0x97d1a0f8, 0xa943152e)}},
+ {{TOBN(0x2cb0ebba, 0x2e1c21dd), TOBN(0xf41b29fc, 0x2c6797c4),
+ TOBN(0xc6e17321, 0xb300101f), TOBN(0x4422b0e9, 0xd0d79a89)},
+ {TOBN(0x49e4901c, 0x92f1bfc4), TOBN(0x06ab1f8f, 0xe1e10ed9),
+ TOBN(0x84d35577, 0xdb2926b8), TOBN(0xca349d39, 0x356e8ec2)}},
+ {{TOBN(0x70b63d32, 0x343bf1a9), TOBN(0x8fd3bd28, 0x37d1a6b1),
+ TOBN(0x0454879c, 0x316865b4), TOBN(0xee959ff6, 0xc458efa2)},
+ {TOBN(0x0461dcf8, 0x9706dc3f), TOBN(0x737db0e2, 0x164e4b2e),
+ TOBN(0x09262680, 0x2f8843c8), TOBN(0x54498bbc, 0x7745e6f6)}},
+ {{TOBN(0x359473fa, 0xa29e24af), TOBN(0xfcc3c454, 0x70aa87a1),
+ TOBN(0xfd2c4bf5, 0x00573ace), TOBN(0xb65b514e, 0x28dd1965)},
+ {TOBN(0xe46ae7cf, 0x2193e393), TOBN(0x60e9a4e1, 0xf5444d97),
+ TOBN(0xe7594e96, 0x00ff38ed), TOBN(0x43d84d2f, 0x0a0e0f02)}},
+ {{TOBN(0x8b6db141, 0xee398a21), TOBN(0xb88a56ae, 0xe3bcc5be),
+ TOBN(0x0a1aa52f, 0x373460ea), TOBN(0x20da1a56, 0x160bb19b)},
+ {TOBN(0xfb54999d, 0x65bf0384), TOBN(0x71a14d24, 0x5d5a180e),
+ TOBN(0xbc44db7b, 0x21737b04), TOBN(0xd84fcb18, 0x01dd8e92)}},
+ {{TOBN(0x80de937b, 0xfa44b479), TOBN(0x53505499, 0x5c98fd4f),
+ TOBN(0x1edb12ab, 0x28f08727), TOBN(0x4c58b582, 0xa5f3ef53)},
+ {TOBN(0xbfb236d8, 0x8327f246), TOBN(0xc3a3bfaa, 0x4d7df320),
+ TOBN(0xecd96c59, 0xb96024f2), TOBN(0xfc293a53, 0x7f4e0433)}},
+ {{TOBN(0x5341352b, 0x5acf6e10), TOBN(0xc50343fd, 0xafe652c3),
+ TOBN(0x4af3792d, 0x18577a7f), TOBN(0xe1a4c617, 0xaf16823d)},
+ {TOBN(0x9b26d0cd, 0x33425d0a), TOBN(0x306399ed, 0x9b7bc47f),
+ TOBN(0x2a792f33, 0x706bb20b), TOBN(0x31219614, 0x98111055)}},
+ {{TOBN(0x864ec064, 0x87f5d28b), TOBN(0x11392d91, 0x962277fd),
+ TOBN(0xb5aa7942, 0xbb6aed5f), TOBN(0x080094dc, 0x47e799d9)},
+ {TOBN(0x4afa588c, 0x208ba19b), TOBN(0xd3e7570f, 0x8512f284),
+ TOBN(0xcbae64e6, 0x02f5799a), TOBN(0xdeebe7ef, 0x514b9492)}},
+ {{TOBN(0x30300f98, 0xe5c298ff), TOBN(0x17f561be, 0x3678361f),
+ TOBN(0xf52ff312, 0x98cb9a16), TOBN(0x6233c3bc, 0x5562d490)},
+ {TOBN(0x7bfa15a1, 0x92e3a2cb), TOBN(0x961bcfd1, 0xe6365119),
+ TOBN(0x3bdd29bf, 0x2c8c53b1), TOBN(0x739704df, 0x822844ba)}},
+ {{TOBN(0x7dacfb58, 0x7e7b754b), TOBN(0x23360791, 0xa806c9b9),
+ TOBN(0xe7eb88c9, 0x23504452), TOBN(0x2983e996, 0x852c1783)},
+ {TOBN(0xdd4ae529, 0x958d881d), TOBN(0x026bae03, 0x262c7b3c),
+ TOBN(0x3a6f9193, 0x960b52d1), TOBN(0xd0980f90, 0x92696cfb)}},
+ {{TOBN(0x4c1f428c, 0xd5f30851), TOBN(0x94dfed27, 0x2a4f6630),
+ TOBN(0x4df53772, 0xfc5d48a4), TOBN(0xdd2d5a2f, 0x933260ce)},
+ {TOBN(0x574115bd, 0xd44cc7a5), TOBN(0x4ba6b20d, 0xbd12533a),
+ TOBN(0x30e93cb8, 0x243057c9), TOBN(0x794c486a, 0x14de320e)}},
+ {{TOBN(0xe925d4ce, 0xf21496e4), TOBN(0xf951d198, 0xec696331),
+ TOBN(0x9810e2de, 0x3e8d812f), TOBN(0xd0a47259, 0x389294ab)},
+ {TOBN(0x513ba2b5, 0x0e3bab66), TOBN(0x462caff5, 0xabad306f),
+ TOBN(0xe2dc6d59, 0xaf04c49e), TOBN(0x1aeb8750, 0xe0b84b0b)}},
+ {{TOBN(0xc034f12f, 0x2f7d0ca2), TOBN(0x6d2e8128, 0xe06acf2f),
+ TOBN(0x801f4f83, 0x21facc2f), TOBN(0xa1170c03, 0xf40ef607)},
+ {TOBN(0xfe0a1d4f, 0x7805a99c), TOBN(0xbde56a36, 0xcc26aba5),
+ TOBN(0x5b1629d0, 0x35531f40), TOBN(0xac212c2b, 0x9afa6108)}},
+ {{TOBN(0x30a06bf3, 0x15697be5), TOBN(0x6f0545dc, 0x2c63c7c1),
+ TOBN(0x5d8cb842, 0x7ccdadaf), TOBN(0xd52e379b, 0xac7015bb)},
+ {TOBN(0xc4f56147, 0xf462c23e), TOBN(0xd44a4298, 0x46bc24b0),
+ TOBN(0xbc73d23a, 0xe2856d4f), TOBN(0x61cedd8c, 0x0832bcdf)}},
+ {{TOBN(0x60953556, 0x99f241d7), TOBN(0xee4adbd7, 0x001a349d),
+ TOBN(0x0b35bf6a, 0xaa89e491), TOBN(0x7f0076f4, 0x136f7546)},
+ {TOBN(0xd19a18ba, 0x9264da3d), TOBN(0x6eb2d2cd, 0x62a7a28b),
+ TOBN(0xcdba941f, 0x8761c971), TOBN(0x1550518b, 0xa3be4a5d)}},
+ {{TOBN(0xd0e8e2f0, 0x57d0b70c), TOBN(0xeea8612e, 0xcd133ba3),
+ TOBN(0x814670f0, 0x44416aec), TOBN(0x424db6c3, 0x30775061)},
+ {TOBN(0xd96039d1, 0x16213fd1), TOBN(0xc61e7fa5, 0x18a3478f),
+ TOBN(0xa805bdcc, 0xcb0c5021), TOBN(0xbdd6f3a8, 0x0cc616dd)}},
+ {{TOBN(0x06009667, 0x5d97f7e2), TOBN(0x31db0fc1, 0xaf0bf4b6),
+ TOBN(0x23680ed4, 0x5491627a), TOBN(0xb99a3c66, 0x7d741fb1)},
+ {TOBN(0xe9bb5f55, 0x36b1ff92), TOBN(0x29738577, 0x512b388d),
+ TOBN(0xdb8a2ce7, 0x50fcf263), TOBN(0x385346d4, 0x6c4f7b47)}},
+ {{TOBN(0xbe86c5ef, 0x31631f9e), TOBN(0xbf91da21, 0x03a57a29),
+ TOBN(0xc3b1f796, 0x7b23f821), TOBN(0x0f7d00d2, 0x770db354)},
+ {TOBN(0x8ffc6c3b, 0xd8fe79da), TOBN(0xcc5e8c40, 0xd525c996),
+ TOBN(0x4640991d, 0xcfff632a), TOBN(0x64d97e8c, 0x67112528)}},
+ {{TOBN(0xc232d973, 0x02f1cd1e), TOBN(0xce87eacb, 0x1dd212a4),
+ TOBN(0x6e4c8c73, 0xe69802f7), TOBN(0x12ef0290, 0x1fffddbd)},
+ {TOBN(0x941ec74e, 0x1bcea6e2), TOBN(0xd0b54024, 0x3cb92cbb),
+ TOBN(0x809fb9d4, 0x7e8f9d05), TOBN(0x3bf16159, 0xf2992aae)}},
+ {{TOBN(0xad40f279, 0xf8a7a838), TOBN(0x11aea631, 0x05615660),
+ TOBN(0xbf52e6f1, 0xa01f6fa1), TOBN(0xef046995, 0x3dc2aec9)},
+ {TOBN(0x785dbec9, 0xd8080711), TOBN(0xe1aec60a, 0x9fdedf76),
+ TOBN(0xece797b5, 0xfa21c126), TOBN(0xc66e898f, 0x05e52732)}},
+ {{TOBN(0x39bb69c4, 0x08811fdb), TOBN(0x8bfe1ef8, 0x2fc7f082),
+ TOBN(0xc8e7a393, 0x174f4138), TOBN(0xfba8ad1d, 0xd58d1f98)},
+ {TOBN(0xbc21d0ce, 0xbfd2fd5b), TOBN(0x0b839a82, 0x6ee60d61),
+ TOBN(0xaacf7658, 0xafd22253), TOBN(0xb526bed8, 0xaae396b3)}},
+ {{TOBN(0xccc1bbc2, 0x38564464), TOBN(0x9e3ff947, 0x8c45bc73),
+ TOBN(0xcde9bca3, 0x58188a78), TOBN(0x138b8ee0, 0xd73bf8f7)},
+ {TOBN(0x5c7e234c, 0x4123c489), TOBN(0x66e69368, 0xfa643297),
+ TOBN(0x0629eeee, 0x39a15fa3), TOBN(0x95fab881, 0xa9e2a927)}},
+ {{TOBN(0xb2497007, 0xeafbb1e1), TOBN(0xd75c9ce6, 0xe75b7a93),
+ TOBN(0x3558352d, 0xefb68d78), TOBN(0xa2f26699, 0x223f6396)},
+ {TOBN(0xeb911ecf, 0xe469b17a), TOBN(0x62545779, 0xe72d3ec2),
+ TOBN(0x8ea47de7, 0x82cb113f), TOBN(0xebe4b086, 0x4e1fa98d)}},
+ {{TOBN(0xec2d5ed7, 0x8cdfedb1), TOBN(0xa535c077, 0xfe211a74),
+ TOBN(0x9678109b, 0x11d244c5), TOBN(0xf17c8bfb, 0xbe299a76)},
+ {TOBN(0xb651412e, 0xfb11fbc4), TOBN(0xea0b5482, 0x94ab3f65),
+ TOBN(0xd8dffd95, 0x0cf78243), TOBN(0x2e719e57, 0xce0361d4)}},
+ {{TOBN(0x9007f085, 0x304ddc5b), TOBN(0x095e8c6d, 0x4daba2ea),
+ TOBN(0x5a33cdb4, 0x3f9d28a9), TOBN(0x85b95cd8, 0xe2283003)},
+ {TOBN(0xbcd6c819, 0xb9744733), TOBN(0x29c5f538, 0xfc7f5783),
+ TOBN(0x6c49b2fa, 0xd59038e4), TOBN(0x68349cc1, 0x3bbe1018)}},
+ {{TOBN(0xcc490c1d, 0x21830ee5), TOBN(0x36f9c4ee, 0xe9bfa297),
+ TOBN(0x58fd7294, 0x48de1a94), TOBN(0xaadb13a8, 0x4e8f2cdc)},
+ {TOBN(0x515eaaa0, 0x81313dba), TOBN(0xc76bb468, 0xc2152dd8),
+ TOBN(0x357f8d75, 0xa653dbf8), TOBN(0xe4d8c4d1, 0xb14ac143)}},
+ {{TOBN(0xbdb8e675, 0xb055cb40), TOBN(0x898f8e7b, 0x977b5167),
+ TOBN(0xecc65651, 0xb82fb863), TOBN(0x56544814, 0x6d88f01f)},
+ {TOBN(0xb0928e95, 0x263a75a9), TOBN(0xcfb6836f, 0x1a22fcda),
+ TOBN(0x651d14db, 0x3f3bd37c), TOBN(0x1d3837fb, 0xb6ad4664)}},
+ {{TOBN(0x7c5fb538, 0xff4f94ab), TOBN(0x7243c712, 0x6d7fb8f2),
+ TOBN(0xef13d60c, 0xa85c5287), TOBN(0x18cfb7c7, 0x4bb8dd1b)},
+ {TOBN(0x82f9bfe6, 0x72908219), TOBN(0x35c4592b, 0x9d5144ab),
+ TOBN(0x52734f37, 0x9cf4b42f), TOBN(0x6bac55e7, 0x8c60ddc4)}},
+ {{TOBN(0xb5cd811e, 0x94dea0f6), TOBN(0x259ecae4, 0xe18cc1a3),
+ TOBN(0x6a0e836e, 0x15e660f8), TOBN(0x6c639ea6, 0x0e02bff2)},
+ {TOBN(0x8721b8cb, 0x7e1026fd), TOBN(0x9e73b50b, 0x63261942),
+ TOBN(0xb8c70974, 0x77f01da3), TOBN(0x1839e6a6, 0x8268f57f)}},
+ {{TOBN(0x571b9415, 0x5150b805), TOBN(0x1892389e, 0xf92c7097),
+ TOBN(0x8d69c18e, 0x4a084b95), TOBN(0x7014c512, 0xbe5b495c)},
+ {TOBN(0x4780db36, 0x1b07523c), TOBN(0x2f6219ce, 0x2c1c64fa),
+ TOBN(0xc38b81b0, 0x602c105a), TOBN(0xab4f4f20, 0x5dc8e360)}},
+ {{TOBN(0x20d3c982, 0xcf7d62d2), TOBN(0x1f36e29d, 0x23ba8150),
+ TOBN(0x48ae0bf0, 0x92763f9e), TOBN(0x7a527e6b, 0x1d3a7007)},
+ {TOBN(0xb4a89097, 0x581a85e3), TOBN(0x1f1a520f, 0xdc158be5),
+ TOBN(0xf98db37d, 0x167d726e), TOBN(0x8802786e, 0x1113e862)}}},
+ {{{TOBN(0xefb2149e, 0x36f09ab0), TOBN(0x03f163ca, 0x4a10bb5b),
+ TOBN(0xd0297045, 0x06e20998), TOBN(0x56f0af00, 0x1b5a3bab)},
+ {TOBN(0x7af4cfec, 0x70880e0d), TOBN(0x7332a66f, 0xbe3d913f),
+ TOBN(0x32e6c84a, 0x7eceb4bd), TOBN(0xedc4a79a, 0x9c228f55)}},
+ {{TOBN(0xc37c7dd0, 0xc55c4496), TOBN(0xa6a96357, 0x25bbabd2),
+ TOBN(0x5b7e63f2, 0xadd7f363), TOBN(0x9dce3782, 0x2e73f1df)},
+ {TOBN(0xe1e5a16a, 0xb2b91f71), TOBN(0xe4489823, 0x5ba0163c),
+ TOBN(0xf2759c32, 0xf6e515ad), TOBN(0xa5e2f1f8, 0x8615eecf)}},
+ {{TOBN(0x74519be7, 0xabded551), TOBN(0x03d358b8, 0xc8b74410),
+ TOBN(0x4d00b10b, 0x0e10d9a9), TOBN(0x6392b0b1, 0x28da52b7)},
+ {TOBN(0x6744a298, 0x0b75c904), TOBN(0xc305b0ae, 0xa8f7f96c),
+ TOBN(0x042e421d, 0x182cf932), TOBN(0xf6fc5d50, 0x9e4636ca)}},
+ {{TOBN(0x795847c9, 0xd64cc78c), TOBN(0x6c50621b, 0x9b6cb27b),
+ TOBN(0x07099bf8, 0xdf8022ab), TOBN(0x48f862eb, 0xc04eda1d)},
+ {TOBN(0xd12732ed, 0xe1603c16), TOBN(0x19a80e0f, 0x5c9a9450),
+ TOBN(0xe2257f54, 0xb429b4fc), TOBN(0x66d3b2c6, 0x45460515)}},
+ {{TOBN(0x6ca4f87e, 0x822e37be), TOBN(0x73f237b4, 0x253bda4e),
+ TOBN(0xf747f3a2, 0x41190aeb), TOBN(0xf06fa36f, 0x804cf284)},
+ {TOBN(0x0a6bbb6e, 0xfc621c12), TOBN(0x5d624b64, 0x40b80ec6),
+ TOBN(0x4b072425, 0x7ba556f3), TOBN(0x7fa0c354, 0x3e2d20a8)}},
+ {{TOBN(0xe921fa31, 0xe3229d41), TOBN(0xa929c652, 0x94531bd4),
+ TOBN(0x84156027, 0xa6d38209), TOBN(0xf3d69f73, 0x6bdb97bd)},
+ {TOBN(0x8906d19a, 0x16833631), TOBN(0x68a34c2e, 0x03d51be3),
+ TOBN(0xcb59583b, 0x0e511cd8), TOBN(0x99ce6bfd, 0xfdc132a8)}},
+ {{TOBN(0x3facdaaa, 0xffcdb463), TOBN(0x658bbc1a, 0x34a38b08),
+ TOBN(0x12a801f8, 0xf1a9078d), TOBN(0x1567bcf9, 0x6ab855de)},
+ {TOBN(0xe08498e0, 0x3572359b), TOBN(0xcf0353e5, 0x8659e68b),
+ TOBN(0xbb86e9c8, 0x7d23807c), TOBN(0xbc08728d, 0x2198e8a2)}},
+ {{TOBN(0x8de2b7bc, 0x453cadd6), TOBN(0x203900a7, 0xbc0bc1f8),
+ TOBN(0xbcd86e47, 0xa6abd3af), TOBN(0x911cac12, 0x8502effb)},
+ {TOBN(0x2d550242, 0xec965469), TOBN(0x0e9f7692, 0x29e0017e),
+ TOBN(0x633f078f, 0x65979885), TOBN(0xfb87d449, 0x4cf751ef)}},
+ {{TOBN(0xe1790e4b, 0xfc25419a), TOBN(0x36467203, 0x4bff3cfd),
+ TOBN(0xc8db6386, 0x25b6e83f), TOBN(0x6cc69f23, 0x6cad6fd2)},
+ {TOBN(0x0219e45a, 0x6bc68bb9), TOBN(0xe43d79b6, 0x297f7334),
+ TOBN(0x7d445368, 0x465dc97c), TOBN(0x4b9eea32, 0x2a0b949a)}},
+ {{TOBN(0x1b96c6ba, 0x6102d021), TOBN(0xeaafac78, 0x2f4461ea),
+ TOBN(0xd4b85c41, 0xc49f19a8), TOBN(0x275c28e4, 0xcf538875)},
+ {TOBN(0x35451a9d, 0xdd2e54e0), TOBN(0x6991adb5, 0x0605618b),
+ TOBN(0x5b8b4bcd, 0x7b36cd24), TOBN(0x372a4f8c, 0x56f37216)}},
+ {{TOBN(0xc890bd73, 0xa6a5da60), TOBN(0x6f083da0, 0xdc4c9ff0),
+ TOBN(0xf4e14d94, 0xf0536e57), TOBN(0xf9ee1eda, 0xaaec8243)},
+ {TOBN(0x571241ec, 0x8bdcf8e7), TOBN(0xa5db8271, 0x0b041e26),
+ TOBN(0x9a0b9a99, 0xe3fff040), TOBN(0xcaaf21dd, 0x7c271202)}},
+ {{TOBN(0xb4e2b2e1, 0x4f0dd2e8), TOBN(0xe77e7c4f, 0x0a377ac7),
+ TOBN(0x69202c3f, 0x0d7a2198), TOBN(0xf759b7ff, 0x28200eb8)},
+ {TOBN(0xc87526ed, 0xdcfe314e), TOBN(0xeb84c524, 0x53d5cf99),
+ TOBN(0xb1b52ace, 0x515138b6), TOBN(0x5aa7ff8c, 0x23fca3f4)}},
+ {{TOBN(0xff0b13c3, 0xb9791a26), TOBN(0x960022da, 0xcdd58b16),
+ TOBN(0xdbd55c92, 0x57aad2de), TOBN(0x3baaaaa3, 0xf30fe619)},
+ {TOBN(0x9a4b2346, 0x0d881efd), TOBN(0x506416c0, 0x46325e2a),
+ TOBN(0x91381e76, 0x035c18d4), TOBN(0xb3bb68be, 0xf27817b0)}},
+ {{TOBN(0x15bfb8bf, 0x5116f937), TOBN(0x7c64a586, 0xc1268943),
+ TOBN(0x71e25cc3, 0x8419a2c8), TOBN(0x9fd6b0c4, 0x8335f463)},
+ {TOBN(0x4bf0ba3c, 0xe8ee0e0e), TOBN(0x6f6fba60, 0x298c21fa),
+ TOBN(0x57d57b39, 0xae66bee0), TOBN(0x292d5130, 0x22672544)}},
+ {{TOBN(0xf451105d, 0xbab093b3), TOBN(0x012f59b9, 0x02839986),
+ TOBN(0x8a915802, 0x3474a89c), TOBN(0x048c919c, 0x2de03e97)},
+ {TOBN(0xc476a2b5, 0x91071cd5), TOBN(0x791ed89a, 0x034970a5),
+ TOBN(0x89bd9042, 0xe1b7994b), TOBN(0x8eaf5179, 0xa1057ffd)}},
+ {{TOBN(0x6066e2a2, 0xd551ee10), TOBN(0x87a8f1d8, 0x727e09a6),
+ TOBN(0x00d08bab, 0x2c01148d), TOBN(0x6da8e4f1, 0x424f33fe)},
+ {TOBN(0x466d17f0, 0xcf9a4e71), TOBN(0xff502010, 0x3bf5cb19),
+ TOBN(0xdccf97d8, 0xd062ecc0), TOBN(0x80c0d9af, 0x81d80ac4)}},
+ {{TOBN(0xe87771d8, 0x033f2876), TOBN(0xb0186ec6, 0x7d5cc3db),
+ TOBN(0x58e8bb80, 0x3bc9bc1d), TOBN(0x4d1395cc, 0x6f6ef60e)},
+ {TOBN(0xa73c62d6, 0x186244a0), TOBN(0x918e5f23, 0x110a5b53),
+ TOBN(0xed4878ca, 0x741b7eab), TOBN(0x3038d71a, 0xdbe03e51)}},
+ {{TOBN(0x840204b7, 0xa93c3246), TOBN(0x21ab6069, 0xa0b9b4cd),
+ TOBN(0xf5fa6e2b, 0xb1d64218), TOBN(0x1de6ad0e, 0xf3d56191)},
+ {TOBN(0x570aaa88, 0xff1929c7), TOBN(0xc6df4c6b, 0x640e87b5),
+ TOBN(0xde8a74f2, 0xc65f0ccc), TOBN(0x8b972fd5, 0xe6f6cc01)}},
+ {{TOBN(0x3fff36b6, 0x0b846531), TOBN(0xba7e45e6, 0x10a5e475),
+ TOBN(0x84a1d10e, 0x4145b6c5), TOBN(0xf1f7f91a, 0x5e046d9d)},
+ {TOBN(0x0317a692, 0x44de90d7), TOBN(0x951a1d4a, 0xf199c15e),
+ TOBN(0x91f78046, 0xc9d73deb), TOBN(0x74c82828, 0xfab8224f)}},
+ {{TOBN(0xaa6778fc, 0xe7560b90), TOBN(0xb4073e61, 0xa7e824ce),
+ TOBN(0xff0d693c, 0xd642eba8), TOBN(0x7ce2e57a, 0x5dccef38)},
+ {TOBN(0x89c2c789, 0x1df1ad46), TOBN(0x83a06922, 0x098346fd),
+ TOBN(0x2d715d72, 0xda2fc177), TOBN(0x7b6dd71d, 0x85b6cf1d)}},
+ {{TOBN(0xc60a6d0a, 0x73fa9cb0), TOBN(0xedd3992e, 0x328bf5a9),
+ TOBN(0xc380ddd0, 0x832c8c82), TOBN(0xd182d410, 0xa2a0bf50)},
+ {TOBN(0x7d9d7438, 0xd9a528db), TOBN(0xe8b1a0e9, 0xcaf53994),
+ TOBN(0xddd6e5fe, 0x0e19987c), TOBN(0xacb8df03, 0x190b059d)}},
+ {{TOBN(0x53703a32, 0x8300129f), TOBN(0x1f637662, 0x68c43bfd),
+ TOBN(0xbcbd1913, 0x00e54051), TOBN(0x812fcc62, 0x7bf5a8c5)},
+ {TOBN(0x3f969d5f, 0x29fb85da), TOBN(0x72f4e00a, 0x694759e8),
+ TOBN(0x426b6e52, 0x790726b7), TOBN(0x617bbc87, 0x3bdbb209)}},
+ {{TOBN(0x511f8bb9, 0x97aee317), TOBN(0x812a4096, 0xe81536a8),
+ TOBN(0x137dfe59, 0x3ac09b9b), TOBN(0x0682238f, 0xba8c9a7a)},
+ {TOBN(0x7072ead6, 0xaeccb4bd), TOBN(0x6a34e9aa, 0x692ba633),
+ TOBN(0xc82eaec2, 0x6fff9d33), TOBN(0xfb753512, 0x1d4d2b62)}},
+ {{TOBN(0x1a0445ff, 0x1d7aadab), TOBN(0x65d38260, 0xd5f6a67c),
+ TOBN(0x6e62fb08, 0x91cfb26f), TOBN(0xef1e0fa5, 0x5c7d91d6)},
+ {TOBN(0x47e7c7ba, 0x33db72cd), TOBN(0x017cbc09, 0xfa7c74b2),
+ TOBN(0x3c931590, 0xf50a503c), TOBN(0xcac54f60, 0x616baa42)}},
+ {{TOBN(0x9b6cd380, 0xb2369f0f), TOBN(0x97d3a70d, 0x23c76151),
+ TOBN(0x5f9dd6fc, 0x9862a9c6), TOBN(0x044c4ab2, 0x12312f51)},
+ {TOBN(0x035ea0fd, 0x834a2ddc), TOBN(0x49e6b862, 0xcc7b826d),
+ TOBN(0xb03d6883, 0x62fce490), TOBN(0x62f2497a, 0xb37e36e9)}},
+ {{TOBN(0x04b005b6, 0xc6458293), TOBN(0x36bb5276, 0xe8d10af7),
+ TOBN(0xacf2dc13, 0x8ee617b8), TOBN(0x470d2d35, 0xb004b3d4)},
+ {TOBN(0x06790832, 0xfeeb1b77), TOBN(0x2bb75c39, 0x85657f9c),
+ TOBN(0xd70bd4ed, 0xc0f60004), TOBN(0xfe797ecc, 0x219b018b)}},
+ {{TOBN(0x9b5bec2a, 0x753aebcc), TOBN(0xdaf9f3dc, 0xc939eca5),
+ TOBN(0xd6bc6833, 0xd095ad09), TOBN(0x98abdd51, 0xdaa4d2fc)},
+ {TOBN(0xd9840a31, 0x8d168be5), TOBN(0xcf7c10e0, 0x2325a23c),
+ TOBN(0xa5c02aa0, 0x7e6ecfaf), TOBN(0x2462e7e6, 0xb5bfdf18)}},
+ {{TOBN(0xab2d8a8b, 0xa0cc3f12), TOBN(0x68dd485d, 0xbc672a29),
+ TOBN(0x72039752, 0x596f2cd3), TOBN(0x5d3eea67, 0xa0cf3d8d)},
+ {TOBN(0x810a1a81, 0xe6602671), TOBN(0x8f144a40, 0x14026c0c),
+ TOBN(0xbc753a6d, 0x76b50f85), TOBN(0xc4dc21e8, 0x645cd4a4)}},
+ {{TOBN(0xc5262dea, 0x521d0378), TOBN(0x802b8e0e, 0x05011c6f),
+ TOBN(0x1ba19cbb, 0x0b4c19ea), TOBN(0x21db64b5, 0xebf0aaec)},
+ {TOBN(0x1f394ee9, 0x70342f9d), TOBN(0x93a10aee, 0x1bc44a14),
+ TOBN(0xa7eed31b, 0x3efd0baa), TOBN(0x6e7c824e, 0x1d154e65)}},
+ {{TOBN(0xee23fa81, 0x9966e7ee), TOBN(0x64ec4aa8, 0x05b7920d),
+ TOBN(0x2d44462d, 0x2d90aad4), TOBN(0xf44dd195, 0xdf277ad5)},
+ {TOBN(0x8d6471f1, 0xbb46b6a1), TOBN(0x1e65d313, 0xfd885090),
+ TOBN(0x33a800f5, 0x13a977b4), TOBN(0xaca9d721, 0x0797e1ef)}},
+ {{TOBN(0x9a5a85a0, 0xfcff6a17), TOBN(0x9970a3f3, 0x1eca7cee),
+ TOBN(0xbb9f0d6b, 0xc9504be3), TOBN(0xe0c504be, 0xadd24ee2)},
+ {TOBN(0x7e09d956, 0x77fcc2f4), TOBN(0xef1a5227, 0x65bb5fc4),
+ TOBN(0x145d4fb1, 0x8b9286aa), TOBN(0x66fd0c5d, 0x6649028b)}},
+ {{TOBN(0x98857ceb, 0x1bf4581c), TOBN(0xe635e186, 0xaca7b166),
+ TOBN(0x278ddd22, 0x659722ac), TOBN(0xa0903c4c, 0x1db68007)},
+ {TOBN(0x366e4589, 0x48f21402), TOBN(0x31b49c14, 0xb96abda2),
+ TOBN(0x329c4b09, 0xe0403190), TOBN(0x97197ca3, 0xd29f43fe)}},
+ {{TOBN(0x8073dd1e, 0x274983d8), TOBN(0xda1a3bde, 0x55717c8f),
+ TOBN(0xfd3d4da2, 0x0361f9d1), TOBN(0x1332d081, 0x4c7de1ce)},
+ {TOBN(0x9b7ef7a3, 0xaa6d0e10), TOBN(0x17db2e73, 0xf54f1c4a),
+ TOBN(0xaf3dffae, 0x4cd35567), TOBN(0xaaa2f406, 0xe56f4e71)}},
+ {{TOBN(0x8966759e, 0x7ace3fc7), TOBN(0x9594eacf, 0x45a8d8c6),
+ TOBN(0x8de3bd8b, 0x91834e0e), TOBN(0xafe4ca53, 0x548c0421)},
+ {TOBN(0xfdd7e856, 0xe6ee81c6), TOBN(0x8f671beb, 0x6b891a3a),
+ TOBN(0xf7a58f2b, 0xfae63829), TOBN(0x9ab186fb, 0x9c11ac9f)}},
+ {{TOBN(0x8d6eb369, 0x10b5be76), TOBN(0x046b7739, 0xfb040bcd),
+ TOBN(0xccb4529f, 0xcb73de88), TOBN(0x1df0fefc, 0xcf26be03)},
+ {TOBN(0xad7757a6, 0xbcfcd027), TOBN(0xa8786c75, 0xbb3165ca),
+ TOBN(0xe9db1e34, 0x7e99a4d9), TOBN(0x99ee86df, 0xb06c504b)}},
+ {{TOBN(0x5b7c2ddd, 0xc15c9f0a), TOBN(0xdf87a734, 0x4295989e),
+ TOBN(0x59ece47c, 0x03d08fda), TOBN(0xb074d3dd, 0xad5fc702)},
+ {TOBN(0x20407903, 0x51a03776), TOBN(0x2bb1f77b, 0x2a608007),
+ TOBN(0x25c58f4f, 0xe1153185), TOBN(0xe6df62f6, 0x766e6447)}},
+ {{TOBN(0xefb3d1be, 0xed51275a), TOBN(0x5de47dc7, 0x2f0f483f),
+ TOBN(0x7932d98e, 0x97c2bedf), TOBN(0xd5c11927, 0x0219f8a1)},
+ {TOBN(0x9d751200, 0xa73a294e), TOBN(0x5f88434a, 0x9dc20172),
+ TOBN(0xd28d9fd3, 0xa26f506a), TOBN(0xa890cd31, 0x9d1dcd48)}},
+ {{TOBN(0x0aebaec1, 0x70f4d3b4), TOBN(0xfd1a1369, 0x0ffc8d00),
+ TOBN(0xb9d9c240, 0x57d57838), TOBN(0x45929d26, 0x68bac361)},
+ {TOBN(0x5a2cd060, 0x25b15ca6), TOBN(0x4b3c83e1, 0x6e474446),
+ TOBN(0x1aac7578, 0xee1e5134), TOBN(0xa418f5d6, 0xc91e2f41)}},
+ {{TOBN(0x6936fc8a, 0x213ed68b), TOBN(0x860ae7ed, 0x510a5224),
+ TOBN(0x63660335, 0xdef09b53), TOBN(0x641b2897, 0xcd79c98d)},
+ {TOBN(0x29bd38e1, 0x01110f35), TOBN(0x79c26f42, 0x648b1937),
+ TOBN(0x64dae519, 0x9d9164f4), TOBN(0xd85a2310, 0x0265c273)}},
+ {{TOBN(0x7173dd5d, 0x4b07e2b1), TOBN(0xd144c4cb, 0x8d9ea221),
+ TOBN(0xe8b04ea4, 0x1105ab14), TOBN(0x92dda542, 0xfe80d8f1)},
+ {TOBN(0xe9982fa8, 0xcf03dce6), TOBN(0x8b5ea965, 0x1a22cffc),
+ TOBN(0xf7f4ea7f, 0x3fad88c4), TOBN(0x62db773e, 0x6a5ba95c)}},
+ {{TOBN(0xd20f02fb, 0x93f24567), TOBN(0xfd46c69a, 0x315257ca),
+ TOBN(0x0ac74cc7, 0x8bcab987), TOBN(0x46f31c01, 0x5ceca2f5)},
+ {TOBN(0x40aedb59, 0x888b219e), TOBN(0xe50ecc37, 0xe1fccd02),
+ TOBN(0x1bcd9dad, 0x911f816c), TOBN(0x583cc1ec, 0x8db9b00c)}},
+ {{TOBN(0xf3cd2e66, 0xa483bf11), TOBN(0xfa08a6f5, 0xb1b2c169),
+ TOBN(0xf375e245, 0x4be9fa28), TOBN(0x99a7ffec, 0x5b6d011f)},
+ {TOBN(0x6a3ebddb, 0xc4ae62da), TOBN(0x6cea00ae, 0x374aef5d),
+ TOBN(0xab5fb98d, 0x9d4d05bc), TOBN(0x7cba1423, 0xd560f252)}},
+ {{TOBN(0x49b2cc21, 0x208490de), TOBN(0x1ca66ec3, 0xbcfb2879),
+ TOBN(0x7f1166b7, 0x1b6fb16f), TOBN(0xfff63e08, 0x65fe5db3)},
+ {TOBN(0xb8345abe, 0x8b2610be), TOBN(0xb732ed80, 0x39de3df4),
+ TOBN(0x0e24ed50, 0x211c32b4), TOBN(0xd10d8a69, 0x848ff27d)}},
+ {{TOBN(0xc1074398, 0xed4de248), TOBN(0xd7cedace, 0x10488927),
+ TOBN(0xa4aa6bf8, 0x85673e13), TOBN(0xb46bae91, 0x6daf30af)},
+ {TOBN(0x07088472, 0xfcef7ad8), TOBN(0x61151608, 0xd4b35e97),
+ TOBN(0xbcfe8f26, 0xdde29986), TOBN(0xeb84c4c7, 0xd5a34c79)}},
+ {{TOBN(0xc1eec55c, 0x164e1214), TOBN(0x891be86d, 0xa147bb03),
+ TOBN(0x9fab4d10, 0x0ba96835), TOBN(0xbf01e9b8, 0xa5c1ae9f)},
+ {TOBN(0x6b4de139, 0xb186ebc0), TOBN(0xd5c74c26, 0x85b91bca),
+ TOBN(0x5086a99c, 0xc2d93854), TOBN(0xeed62a7b, 0xa7a9dfbc)}},
+ {{TOBN(0x8778ed6f, 0x76b7618a), TOBN(0xbff750a5, 0x03b66062),
+ TOBN(0x4cb7be22, 0xb65186db), TOBN(0x369dfbf0, 0xcc3a6d13)},
+ {TOBN(0xc7dab26c, 0x7191a321), TOBN(0x9edac3f9, 0x40ed718e),
+ TOBN(0xbc142b36, 0xd0cfd183), TOBN(0xc8af82f6, 0x7c991693)}},
+ {{TOBN(0xb3d1e4d8, 0x97ce0b2a), TOBN(0xe6d7c87f, 0xc3a55cdf),
+ TOBN(0x35846b95, 0x68b81afe), TOBN(0x018d12af, 0xd3c239d8)},
+ {TOBN(0x2b2c6208, 0x01206e15), TOBN(0xe0e42453, 0xa3b882c6),
+ TOBN(0x854470a3, 0xa50162d5), TOBN(0x08157478, 0x7017a62a)}},
+ {{TOBN(0x18bd3fb4, 0x820357c7), TOBN(0x992039ae, 0x6f1458ad),
+ TOBN(0x9a1df3c5, 0x25b44aa1), TOBN(0x2d780357, 0xed3d5281)},
+ {TOBN(0x58cf7e4d, 0xc77ad4d4), TOBN(0xd49a7998, 0xf9df4fc4),
+ TOBN(0x4465a8b5, 0x1d71205e), TOBN(0xa0ee0ea6, 0x649254aa)}},
+ {{TOBN(0x4b5eeecf, 0xab7bd771), TOBN(0x6c873073, 0x35c262b9),
+ TOBN(0xdc5bd648, 0x3c9d61e7), TOBN(0x233d6d54, 0x321460d2)},
+ {TOBN(0xd20c5626, 0xfc195bcc), TOBN(0x25445958, 0x04d78b63),
+ TOBN(0xe03fcb3d, 0x17ec8ef3), TOBN(0x54b690d1, 0x46b8f781)}},
+ {{TOBN(0x82fa2c8a, 0x21230646), TOBN(0xf51aabb9, 0x084f418c),
+ TOBN(0xff4fbec1, 0x1a30ba43), TOBN(0x6a5acf73, 0x743c9df7)},
+ {TOBN(0x1da2b357, 0xd635b4d5), TOBN(0xc3de68dd, 0xecd5c1da),
+ TOBN(0xa689080b, 0xd61af0dd), TOBN(0xdea5938a, 0xd665bf99)}},
+ {{TOBN(0x0231d71a, 0xfe637294), TOBN(0x01968aa6, 0xa5a81cd8),
+ TOBN(0x11252d50, 0x048e63b5), TOBN(0xc446bc52, 0x6ca007e9)},
+ {TOBN(0xef8c50a6, 0x96d6134b), TOBN(0x9361fbf5, 0x9e09a05c),
+ TOBN(0xf17f85a6, 0xdca3291a), TOBN(0xb178d548, 0xff251a21)}},
+ {{TOBN(0x87f6374b, 0xa4df3915), TOBN(0x566ce1bf, 0x2fd5d608),
+ TOBN(0x425cba4d, 0x7de35102), TOBN(0x6b745f8f, 0x58c5d5e2)},
+ {TOBN(0x88402af6, 0x63122edf), TOBN(0x3190f9ed, 0x3b989a89),
+ TOBN(0x4ad3d387, 0xebba3156), TOBN(0xef385ad9, 0xc7c469a5)}},
+ {{TOBN(0xb08281de, 0x3f642c29), TOBN(0x20be0888, 0x910ffb88),
+ TOBN(0xf353dd4a, 0xd5292546), TOBN(0x3f1627de, 0x8377a262)},
+ {TOBN(0xa5faa013, 0xeefcd638), TOBN(0x8f3bf626, 0x74cc77c3),
+ TOBN(0x32618f65, 0xa348f55e), TOBN(0x5787c0dc, 0x9fefeb9e)}},
+ {{TOBN(0xf1673aa2, 0xd9a23e44), TOBN(0x88dfa993, 0x4e10690d),
+ TOBN(0x1ced1b36, 0x2bf91108), TOBN(0x9193ceca, 0x3af48649)},
+ {TOBN(0xfb34327d, 0x2d738fc5), TOBN(0x6697b037, 0x975fee6c),
+ TOBN(0x2f485da0, 0xc04079a5), TOBN(0x2cdf5735, 0x2feaa1ac)}},
+ {{TOBN(0x76944420, 0xbd55659e), TOBN(0x7973e32b, 0x4376090c),
+ TOBN(0x86bb4fe1, 0x163b591a), TOBN(0x10441aed, 0xc196f0ca)},
+ {TOBN(0x3b431f4a, 0x045ad915), TOBN(0x6c11b437, 0xa4afacb1),
+ TOBN(0x30b0c7db, 0x71fdbbd8), TOBN(0xb642931f, 0xeda65acd)}},
+ {{TOBN(0x4baae6e8, 0x9c92b235), TOBN(0xa73bbd0e, 0x6b3993a1),
+ TOBN(0xd06d60ec, 0x693dd031), TOBN(0x03cab91b, 0x7156881c)},
+ {TOBN(0xd615862f, 0x1db3574b), TOBN(0x485b0185, 0x64bb061a),
+ TOBN(0x27434988, 0xa0181e06), TOBN(0x2cd61ad4, 0xc1c0c757)}},
+ {{TOBN(0x3effed5a, 0x2ff9f403), TOBN(0x8dc98d8b, 0x62239029),
+ TOBN(0x2206021e, 0x1f17b70d), TOBN(0xafbec0ca, 0xbf510015)},
+ {TOBN(0x9fed7164, 0x80130dfa), TOBN(0x306dc2b5, 0x8a02dcf5),
+ TOBN(0x48f06620, 0xfeb10fc0), TOBN(0x78d1e1d5, 0x5a57cf51)}},
+ {{TOBN(0xadef8c5a, 0x192ef710), TOBN(0x88afbd4b, 0x3b7431f9),
+ TOBN(0x7e1f7407, 0x64250c9e), TOBN(0x6e31318d, 0xb58bec07)},
+ {TOBN(0xfd4fc4b8, 0x24f89b4e), TOBN(0x65a5dd88, 0x48c36a2a),
+ TOBN(0x4f1eccff, 0xf024baa7), TOBN(0x22a21cf2, 0xcba94650)}},
+ {{TOBN(0x95d29dee, 0x42a554f7), TOBN(0x828983a5, 0x002ec4ba),
+ TOBN(0x8112a1f7, 0x8badb73d), TOBN(0x79ea8897, 0xa27c1839)},
+ {TOBN(0x8969a5a7, 0xd065fd83), TOBN(0xf49af791, 0xb262a0bc),
+ TOBN(0xfcdea8b6, 0xaf2b5127), TOBN(0x10e913e1, 0x564c2dbc)}},
+ {{TOBN(0x51239d14, 0xbc21ef51), TOBN(0xe51c3ceb, 0x4ce57292),
+ TOBN(0x795ff068, 0x47bbcc3b), TOBN(0x86b46e1e, 0xbd7e11e6)},
+ {TOBN(0x0ea6ba23, 0x80041ef4), TOBN(0xd72fe505, 0x6262342e),
+ TOBN(0x8abc6dfd, 0x31d294d4), TOBN(0xbbe017a2, 0x1278c2c9)}},
+ {{TOBN(0xb1fcfa09, 0xb389328a), TOBN(0x322fbc62, 0xd01771b5),
+ TOBN(0x04c0d063, 0x60b045bf), TOBN(0xdb652edc, 0x10e52d01)},
+ {TOBN(0x50ef932c, 0x03ec6627), TOBN(0xde1b3b2d, 0xc1ee50e3),
+ TOBN(0x5ab7bdc5, 0xdc37a90d), TOBN(0xfea67213, 0x31e33a96)}},
+ {{TOBN(0x6482b5cb, 0x4f2999aa), TOBN(0x38476cc6, 0xb8cbf0dd),
+ TOBN(0x93ebfacb, 0x173405bb), TOBN(0x15cdafe7, 0xe52369ec)},
+ {TOBN(0xd42d5ba4, 0xd935b7db), TOBN(0x648b6004, 0x1c99a4cd),
+ TOBN(0x785101bd, 0xa3b5545b), TOBN(0x4bf2c38a, 0x9dd67faf)}},
+ {{TOBN(0xb1aadc63, 0x4442449c), TOBN(0xe0e9921a, 0x33ad4fb8),
+ TOBN(0x5c552313, 0xaa686d82), TOBN(0xdee635fa, 0x465d866c)},
+ {TOBN(0xbc3c224a, 0x18ee6e8a), TOBN(0xeed748a6, 0xed42e02f),
+ TOBN(0xe70f930a, 0xd474cd08), TOBN(0x774ea6ec, 0xfff24adf)}},
+ {{TOBN(0x03e2de1c, 0xf3480d4a), TOBN(0xf0d8edc7, 0xbc8acf1a),
+ TOBN(0xf23e3303, 0x68295a9c), TOBN(0xfadd5f68, 0xc546a97d)},
+ {TOBN(0x895597ad, 0x96f8acb1), TOBN(0xbddd49d5, 0x671bdae2),
+ TOBN(0x16fcd528, 0x21dd43f4), TOBN(0xa5a45412, 0x6619141a)}}},
+ {{{TOBN(0x8ce9b6bf, 0xc360e25a), TOBN(0xe6425195, 0x075a1a78),
+ TOBN(0x9dc756a8, 0x481732f4), TOBN(0x83c0440f, 0x5432b57a)},
+ {TOBN(0xc670b3f1, 0xd720281f), TOBN(0x2205910e, 0xd135e051),
+ TOBN(0xded14b0e, 0xdb052be7), TOBN(0x697b3d27, 0xc568ea39)}},
+ {{TOBN(0x2e599b9a, 0xfb3ff9ed), TOBN(0x28c2e0ab, 0x17f6515c),
+ TOBN(0x1cbee4fd, 0x474da449), TOBN(0x071279a4, 0x4f364452)},
+ {TOBN(0x97abff66, 0x01fbe855), TOBN(0x3ee394e8, 0x5fda51c4),
+ TOBN(0x190385f6, 0x67597c0b), TOBN(0x6e9fccc6, 0xa27ee34b)}},
+ {{TOBN(0x0b89de93, 0x14092ebb), TOBN(0xf17256bd, 0x428e240c),
+ TOBN(0xcf89a7f3, 0x93d2f064), TOBN(0x4f57841e, 0xe1ed3b14)},
+ {TOBN(0x4ee14405, 0xe708d855), TOBN(0x856aae72, 0x03f1c3d0),
+ TOBN(0xc8e5424f, 0xbdd7eed5), TOBN(0x3333e4ef, 0x73ab4270)}},
+ {{TOBN(0x3bc77ade, 0xdda492f8), TOBN(0xc11a3aea, 0x78297205),
+ TOBN(0x5e89a3e7, 0x34931b4c), TOBN(0x17512e2e, 0x9f5694bb)},
+ {TOBN(0x5dc349f3, 0x177bf8b6), TOBN(0x232ea4ba, 0x08c7ff3e),
+ TOBN(0x9c4f9d16, 0xf511145d), TOBN(0xccf109a3, 0x33b379c3)}},
+ {{TOBN(0xe75e7a88, 0xa1f25897), TOBN(0x7ac6961f, 0xa1b5d4d8),
+ TOBN(0xe3e10773, 0x08f3ed5c), TOBN(0x208a54ec, 0x0a892dfb)},
+ {TOBN(0xbe826e19, 0x78660710), TOBN(0x0cf70a97, 0x237df2c8),
+ TOBN(0x418a7340, 0xed704da5), TOBN(0xa3eeb9a9, 0x08ca33fd)}},
+ {{TOBN(0x49d96233, 0x169bca96), TOBN(0x04d286d4, 0x2da6aafb),
+ TOBN(0xc09606ec, 0xa0c2fa94), TOBN(0x8869d0d5, 0x23ff0fb3)},
+ {TOBN(0xa99937e5, 0xd0150d65), TOBN(0xa92e2503, 0x240c14c9),
+ TOBN(0x656bf945, 0x108e2d49), TOBN(0x152a733a, 0xa2f59e2b)}},
+ {{TOBN(0xb4323d58, 0x8434a920), TOBN(0xc0af8e93, 0x622103c5),
+ TOBN(0x667518ef, 0x938dbf9a), TOBN(0xa1843073, 0x83a9cdf2)},
+ {TOBN(0x350a94aa, 0x5447ab80), TOBN(0xe5e5a325, 0xc75a3d61),
+ TOBN(0x74ba507f, 0x68411a9e), TOBN(0x10581fc1, 0x594f70c5)}},
+ {{TOBN(0x60e28570, 0x80eb24a9), TOBN(0x7bedfb4d, 0x488e0cfd),
+ TOBN(0x721ebbd7, 0xc259cdb8), TOBN(0x0b0da855, 0xbc6390a9)},
+ {TOBN(0x2b4d04db, 0xde314c70), TOBN(0xcdbf1fbc, 0x6c32e846),
+ TOBN(0x33833eab, 0xb162fc9e), TOBN(0x9939b48b, 0xb0dd3ab7)}},
+ {{TOBN(0x5aaa98a7, 0xcb0c9c8c), TOBN(0x75105f30, 0x81c4375c),
+ TOBN(0xceee5057, 0x5ef1c90f), TOBN(0xb31e065f, 0xc23a17bf)},
+ {TOBN(0x5364d275, 0xd4b6d45a), TOBN(0xd363f3ad, 0x62ec8996),
+ TOBN(0xb5d21239, 0x4391c65b), TOBN(0x84564765, 0xebb41b47)}},
+ {{TOBN(0x20d18ecc, 0x37107c78), TOBN(0xacff3b6b, 0x570c2a66),
+ TOBN(0x22f975d9, 0x9bd0d845), TOBN(0xef0a0c46, 0xba178fa0)},
+ {TOBN(0x1a419651, 0x76b6028e), TOBN(0xc49ec674, 0x248612d4),
+ TOBN(0x5b6ac4f2, 0x7338af55), TOBN(0x06145e62, 0x7bee5a36)}},
+ {{TOBN(0x33e95d07, 0xe75746b5), TOBN(0x1c1e1f6d, 0xc40c78be),
+ TOBN(0x967833ef, 0x222ff8e2), TOBN(0x4bedcf6a, 0xb49180ad)},
+ {TOBN(0x6b37e9c1, 0x3d7a4c8a), TOBN(0x2748887c, 0x6ddfe760),
+ TOBN(0xf7055123, 0xaa3a5bbc), TOBN(0x954ff225, 0x7bbb8e74)}},
+ {{TOBN(0xc42b8ab1, 0x97c3dfb9), TOBN(0x55a549b0, 0xcf168154),
+ TOBN(0xad6748e7, 0xc1b50692), TOBN(0x2775780f, 0x6fc5cbcb)},
+ {TOBN(0x4eab80b8, 0xe1c9d7c8), TOBN(0x8c69dae1, 0x3fdbcd56),
+ TOBN(0x47e6b4fb, 0x9969eace), TOBN(0x002f1085, 0xa705cb5a)}},
+ {{TOBN(0x4e23ca44, 0x6d3fea55), TOBN(0xb4ae9c86, 0xf4810568),
+ TOBN(0x47bfb91b, 0x2a62f27d), TOBN(0x60deb4c9, 0xd9bac28c)},
+ {TOBN(0xa892d894, 0x7de6c34c), TOBN(0x4ee68259, 0x4494587d),
+ TOBN(0x914ee14e, 0x1a3f8a5b), TOBN(0xbb113eaa, 0x28700385)}},
+ {{TOBN(0x81ca03b9, 0x2115b4c9), TOBN(0x7c163d38, 0x8908cad1),
+ TOBN(0xc912a118, 0xaa18179a), TOBN(0xe09ed750, 0x886e3081)},
+ {TOBN(0xa676e3fa, 0x26f516ca), TOBN(0x753cacf7, 0x8e732f91),
+ TOBN(0x51592aea, 0x833da8b4), TOBN(0xc626f42f, 0x4cbea8aa)}},
+ {{TOBN(0xef9dc899, 0xa7b56eaf), TOBN(0x00c0e52c, 0x34ef7316),
+ TOBN(0x5b1e4e24, 0xfe818a86), TOBN(0x9d31e20d, 0xc538be47)},
+ {TOBN(0x22eb932d, 0x3ed68974), TOBN(0xe44bbc08, 0x7c4e87c4),
+ TOBN(0x4121086e, 0x0dde9aef), TOBN(0x8e6b9cff, 0x134f4345)}},
+ {{TOBN(0x96892c1f, 0x711b0eb9), TOBN(0xb905f2c8, 0x780ab954),
+ TOBN(0xace26309, 0xa20792db), TOBN(0xec8ac9b3, 0x0684e126)},
+ {TOBN(0x486ad8b6, 0xb40a2447), TOBN(0x60121fc1, 0x9fe3fb24),
+ TOBN(0x5626fccf, 0x1a8e3b3f), TOBN(0x4e568622, 0x6ad1f394)}},
+ {{TOBN(0xda7aae0d, 0x196aa5a1), TOBN(0xe0df8c77, 0x1041b5fb),
+ TOBN(0x451465d9, 0x26b318b7), TOBN(0xc29b6e55, 0x7ab136e9)},
+ {TOBN(0x2c2ab48b, 0x71148463), TOBN(0xb5738de3, 0x64454a76),
+ TOBN(0x54ccf9a0, 0x5a03abe4), TOBN(0x377c0296, 0x0427d58e)}},
+ {{TOBN(0x73f5f0b9, 0x2bb39c1f), TOBN(0x14373f2c, 0xe608d8c5),
+ TOBN(0xdcbfd314, 0x00fbb805), TOBN(0xdf18fb20, 0x83afdcfb)},
+ {TOBN(0x81a57f42, 0x42b3523f), TOBN(0xe958532d, 0x87f650fb),
+ TOBN(0xaa8dc8b6, 0x8b0a7d7c), TOBN(0x1b75dfb7, 0x150166be)}},
+ {{TOBN(0x90e4f7c9, 0x2d7d1413), TOBN(0x67e2d6b5, 0x9834f597),
+ TOBN(0x4fd4f4f9, 0xa808c3e8), TOBN(0xaf8237e0, 0xd5281ec1)},
+ {TOBN(0x25ab5fdc, 0x84687cee), TOBN(0xc5ded6b1, 0xa5b26c09),
+ TOBN(0x8e4a5aec, 0xc8ea7650), TOBN(0x23b73e5c, 0x14cc417f)}},
+ {{TOBN(0x2bfb4318, 0x3037bf52), TOBN(0xb61e6db5, 0x78c725d7),
+ TOBN(0x8efd4060, 0xbbb3e5d7), TOBN(0x2e014701, 0xdbac488e)},
+ {TOBN(0xac75cf9a, 0x360aa449), TOBN(0xb70cfd05, 0x79634d08),
+ TOBN(0xa591536d, 0xfffb15ef), TOBN(0xb2c37582, 0xd07c106c)}},
+ {{TOBN(0xb4293fdc, 0xf50225f9), TOBN(0xc52e175c, 0xb0e12b03),
+ TOBN(0xf649c3ba, 0xd0a8bf64), TOBN(0x745a8fef, 0xeb8ae3c6)},
+ {TOBN(0x30d7e5a3, 0x58321bc3), TOBN(0xb1732be7, 0x0bc4df48),
+ TOBN(0x1f217993, 0xe9ea5058), TOBN(0xf7a71cde, 0x3e4fd745)}},
+ {{TOBN(0x86cc533e, 0x894c5bbb), TOBN(0x6915c7d9, 0x69d83082),
+ TOBN(0xa6aa2d05, 0x5815c244), TOBN(0xaeeee592, 0x49b22ce5)},
+ {TOBN(0x89e39d13, 0x78135486), TOBN(0x3a275c1f, 0x16b76f2f),
+ TOBN(0xdb6bcc1b, 0xe036e8f5), TOBN(0x4df69b21, 0x5e4709f5)}},
+ {{TOBN(0xa188b250, 0x2d0f39aa), TOBN(0x622118bb, 0x15a85947),
+ TOBN(0x2ebf520f, 0xfde0f4fa), TOBN(0xa40e9f29, 0x4860e539)},
+ {TOBN(0x7b6a51eb, 0x22b57f0f), TOBN(0x849a33b9, 0x7e80644a),
+ TOBN(0x50e5d16f, 0x1cf095fe), TOBN(0xd754b54e, 0xec55f002)}},
+ {{TOBN(0x5cfbbb22, 0x236f4a98), TOBN(0x0b0c59e9, 0x066800bb),
+ TOBN(0x4ac69a8f, 0x5a9a7774), TOBN(0x2b33f804, 0xd6bec948)},
+ {TOBN(0xb3729295, 0x32e6c466), TOBN(0x68956d0f, 0x4e599c73),
+ TOBN(0xa47a249f, 0x155c31cc), TOBN(0x24d80f0d, 0xe1ce284e)}},
+ {{TOBN(0xcd821dfb, 0x988baf01), TOBN(0xe6331a7d, 0xdbb16647),
+ TOBN(0x1eb8ad33, 0x094cb960), TOBN(0x593cca38, 0xc91bbca5)},
+ {TOBN(0x384aac8d, 0x26567456), TOBN(0x40fa0309, 0xc04b6490),
+ TOBN(0x97834cd6, 0xdab6c8f6), TOBN(0x68a7318d, 0x3f91e55f)}},
+ {{TOBN(0xa00fd04e, 0xfc4d3157), TOBN(0xb56f8ab2, 0x2bf3bdea),
+ TOBN(0x014f5648, 0x4fa57172), TOBN(0x948c5860, 0x450abdb3)},
+ {TOBN(0x342b5df0, 0x0ebd4f08), TOBN(0x3e5168cd, 0x0e82938e),
+ TOBN(0x7aedc1ce, 0xb0df5dd0), TOBN(0x6bbbc6d9, 0xe5732516)}},
+ {{TOBN(0xc7bfd486, 0x605daaa6), TOBN(0x46fd72b7, 0xbb9a6c9e),
+ TOBN(0xe4847fb1, 0xa124fb89), TOBN(0x75959cbd, 0xa2d8ffbc)},
+ {TOBN(0x42579f65, 0xc8a588ee), TOBN(0x368c92e6, 0xb80b499d),
+ TOBN(0xea4ef6cd, 0x999a5df1), TOBN(0xaa73bb7f, 0x936fe604)}},
+ {{TOBN(0xf347a70d, 0x6457d188), TOBN(0x86eda86b, 0x8b7a388b),
+ TOBN(0xb7cdff06, 0x0ccd6013), TOBN(0xbeb1b6c7, 0xd0053fb2)},
+ {TOBN(0x0b022387, 0x99240a9f), TOBN(0x1bbb384f, 0x776189b2),
+ TOBN(0x8695e71e, 0x9066193a), TOBN(0x2eb50097, 0x06ffac7e)}},
+ {{TOBN(0x0654a9c0, 0x4a7d2caa), TOBN(0x6f3fb3d1, 0xa5aaa290),
+ TOBN(0x835db041, 0xff476e8f), TOBN(0x540b8b0b, 0xc42295e4)},
+ {TOBN(0xa5c73ac9, 0x05e214f5), TOBN(0x9a74075a, 0x56a0b638),
+ TOBN(0x2e4b1090, 0xce9e680b), TOBN(0x57a5b479, 0x6b8d9afa)}},
+ {{TOBN(0x0dca48e7, 0x26bfe65c), TOBN(0x097e391c, 0x7290c307),
+ TOBN(0x683c462e, 0x6669e72e), TOBN(0xf505be1e, 0x062559ac)},
+ {TOBN(0x5fbe3ea1, 0xe3a3035a), TOBN(0x6431ebf6, 0x9cd50da8),
+ TOBN(0xfd169d5c, 0x1f6407f2), TOBN(0x8d838a95, 0x60fce6b8)}},
+ {{TOBN(0x2a2bfa7f, 0x650006f0), TOBN(0xdfd7dad3, 0x50c0fbb2),
+ TOBN(0x92452495, 0xccf9ad96), TOBN(0x183bf494, 0xd95635f9)},
+ {TOBN(0x02d5df43, 0x4a7bd989), TOBN(0x505385cc, 0xa5431095),
+ TOBN(0xdd98e67d, 0xfd43f53e), TOBN(0xd61e1a6c, 0x500c34a9)}},
+ {{TOBN(0x5a4b46c6, 0x4a8a3d62), TOBN(0x8469c4d0, 0x247743d2),
+ TOBN(0x2bb3a13d, 0x88f7e433), TOBN(0x62b23a10, 0x01be5849)},
+ {TOBN(0xe83596b4, 0xa63d1a4c), TOBN(0x454e7fea, 0x7d183f3e),
+ TOBN(0x643fce61, 0x17afb01c), TOBN(0x4e65e5e6, 0x1c4c3638)}},
+ {{TOBN(0x41d85ea1, 0xef74c45b), TOBN(0x2cfbfa66, 0xae328506),
+ TOBN(0x98b078f5, 0x3ada7da9), TOBN(0xd985fe37, 0xec752fbb)},
+ {TOBN(0xeece68fe, 0x5a0148b4), TOBN(0x6f9a55c7, 0x2d78136d),
+ TOBN(0x232dccc4, 0xd2b729ce), TOBN(0xa27e0dfd, 0x90aafbc4)}},
+ {{TOBN(0x96474452, 0x12b4603e), TOBN(0xa876c551, 0x6b706d14),
+ TOBN(0xdf145fcf, 0x69a9d412), TOBN(0xe2ab75b7, 0x2d479c34)},
+ {TOBN(0x12df9a76, 0x1a23ff97), TOBN(0xc6138992, 0x5d359d10),
+ TOBN(0x6e51c7ae, 0xfa835f22), TOBN(0x69a79cb1, 0xc0fcc4d9)}},
+ {{TOBN(0xf57f350d, 0x594cc7e1), TOBN(0x3079ca63, 0x3350ab79),
+ TOBN(0x226fb614, 0x9aff594a), TOBN(0x35afec02, 0x6d59a62b)},
+ {TOBN(0x9bee46f4, 0x06ed2c6e), TOBN(0x58da1735, 0x7d939a57),
+ TOBN(0x44c50402, 0x8fd1797e), TOBN(0xd8853e7c, 0x5ccea6ca)}},
+ {{TOBN(0x4065508d, 0xa35fcd5f), TOBN(0x8965df8c, 0x495ccaeb),
+ TOBN(0x0f2da850, 0x12e1a962), TOBN(0xee471b94, 0xc1cf1cc4)},
+ {TOBN(0xcef19bc8, 0x0a08fb75), TOBN(0x704958f5, 0x81de3591),
+ TOBN(0x2867f8b2, 0x3aef4f88), TOBN(0x8d749384, 0xea9f9a5f)}},
+ {{TOBN(0x1b385537, 0x8c9049f4), TOBN(0x5be948f3, 0x7b92d8b6),
+ TOBN(0xd96f725d, 0xb6e2bd6b), TOBN(0x37a222bc, 0x958c454d)},
+ {TOBN(0xe7c61abb, 0x8809bf61), TOBN(0x46f07fbc, 0x1346f18d),
+ TOBN(0xfb567a7a, 0xe87c0d1c), TOBN(0x84a461c8, 0x7ef3d07a)}},
+ {{TOBN(0x0a5adce6, 0xd9278d98), TOBN(0x24d94813, 0x9dfc73e1),
+ TOBN(0x4f3528b6, 0x054321c3), TOBN(0x2e03fdde, 0x692ea706)},
+ {TOBN(0x10e60619, 0x47b533c0), TOBN(0x1a8bc73f, 0x2ca3c055),
+ TOBN(0xae58d4b2, 0x1bb62b8f), TOBN(0xb2045a73, 0x584a24e3)}},
+ {{TOBN(0x3ab3d5af, 0xbd76e195), TOBN(0x478dd1ad, 0x6938a810),
+ TOBN(0x6ffab393, 0x6ee3d5cb), TOBN(0xdfb693db, 0x22b361e4)},
+ {TOBN(0xf9694496, 0x51dbf1a7), TOBN(0xcab4b4ef, 0x08a2e762),
+ TOBN(0xe8c92f25, 0xd39bba9a), TOBN(0x850e61bc, 0xf1464d96)}},
+ {{TOBN(0xb7e830e3, 0xdc09508b), TOBN(0xfaf6d2cf, 0x74317655),
+ TOBN(0x72606ceb, 0xdf690355), TOBN(0x48bb92b3, 0xd0c3ded6)},
+ {TOBN(0x65b75484, 0x5c7cf892), TOBN(0xf6cd7ac9, 0xd5d5f01f),
+ TOBN(0xc2c30a59, 0x96401d69), TOBN(0x91268650, 0xed921878)}},
+ {{TOBN(0x380bf913, 0xb78c558f), TOBN(0x43c0baeb, 0xc8afdaa9),
+ TOBN(0x377f61d5, 0x54f169d3), TOBN(0xf8da07e3, 0xae5ff20b)},
+ {TOBN(0xb676c49d, 0xa8a90ea8), TOBN(0x81c1ff2b, 0x83a29b21),
+ TOBN(0x383297ac, 0x2ad8d276), TOBN(0x3001122f, 0xba89f982)}},
+ {{TOBN(0xe1d794be, 0x6718e448), TOBN(0x246c1482, 0x7c3e6e13),
+ TOBN(0x56646ef8, 0x5d26b5ef), TOBN(0x80f5091e, 0x88069cdd)},
+ {TOBN(0xc5992e2f, 0x724bdd38), TOBN(0x02e915b4, 0x8471e8c7),
+ TOBN(0x96ff320a, 0x0d0ff2a9), TOBN(0xbf886487, 0x4384d1a0)}},
+ {{TOBN(0xbbe1e6a6, 0xc93f72d6), TOBN(0xd5f75d12, 0xcad800ea),
+ TOBN(0xfa40a09f, 0xe7acf117), TOBN(0x32c8cdd5, 0x7581a355)},
+ {TOBN(0x74221992, 0x7023c499), TOBN(0xa8afe5d7, 0x38ec3901),
+ TOBN(0x5691afcb, 0xa90e83f0), TOBN(0x41bcaa03, 0x0b8f8eac)}},
+ {{TOBN(0xe38b5ff9, 0x8d2668d5), TOBN(0x0715281a, 0x7ad81965),
+ TOBN(0x1bc8fc7c, 0x03c6ce11), TOBN(0xcbbee6e2, 0x8b650436)},
+ {TOBN(0x06b00fe8, 0x0cdb9808), TOBN(0x17d6e066, 0xfe3ed315),
+ TOBN(0x2e9d38c6, 0x4d0b5018), TOBN(0xab8bfd56, 0x844dcaef)}},
+ {{TOBN(0x42894a59, 0x513aed8b), TOBN(0xf77f3b6d, 0x314bd07a),
+ TOBN(0xbbdecb8f, 0x8e42b582), TOBN(0xf10e2fa8, 0xd2390fe6)},
+ {TOBN(0xefb95022, 0x62a2f201), TOBN(0x4d59ea50, 0x50ee32b0),
+ TOBN(0xd87f7728, 0x6da789a8), TOBN(0xcf98a2cf, 0xf79492c4)}},
+ {{TOBN(0xf9577239, 0x720943c2), TOBN(0xba044cf5, 0x3990b9d0),
+ TOBN(0x5aa8e823, 0x95f2884a), TOBN(0x834de6ed, 0x0278a0af)},
+ {TOBN(0xc8e1ee9a, 0x5f25bd12), TOBN(0x9259ceaa, 0x6f7ab271),
+ TOBN(0x7e6d97a2, 0x77d00b76), TOBN(0x5c0c6eea, 0xa437832a)}},
+ {{TOBN(0x5232c20f, 0x5606b81d), TOBN(0xabd7b375, 0x0d991ee5),
+ TOBN(0x4d2bfe35, 0x8632d951), TOBN(0x78f85146, 0x98ed9364)},
+ {TOBN(0x951873f0, 0xf30c3282), TOBN(0x0da8ac80, 0xa789230b),
+ TOBN(0x3ac7789c, 0x5398967f), TOBN(0xa69b8f7f, 0xbdda0fb5)}},
+ {{TOBN(0xe5db7717, 0x6add8545), TOBN(0x1b71cb66, 0x72c49b66),
+ TOBN(0xd8560739, 0x68421d77), TOBN(0x03840fe8, 0x83e3afea)},
+ {TOBN(0xb391dad5, 0x1ec69977), TOBN(0xae243fb9, 0x307f6726),
+ TOBN(0xc88ac87b, 0xe8ca160c), TOBN(0x5174cced, 0x4ce355f4)}},
+ {{TOBN(0x98a35966, 0xe58ba37d), TOBN(0xfdcc8da2, 0x7817335d),
+ TOBN(0x5b752830, 0x83fbc7bf), TOBN(0x68e419d4, 0xd9c96984)},
+ {TOBN(0x409a39f4, 0x02a40380), TOBN(0x88940faf, 0x1fe977bc),
+ TOBN(0xc640a94b, 0x8f8edea6), TOBN(0x1e22cd17, 0xed11547d)}},
+ {{TOBN(0xe28568ce, 0x59ffc3e2), TOBN(0x60aa1b55, 0xc1dee4e7),
+ TOBN(0xc67497c8, 0x837cb363), TOBN(0x06fb438a, 0x105a2bf2)},
+ {TOBN(0x30357ec4, 0x500d8e20), TOBN(0x1ad9095d, 0x0670db10),
+ TOBN(0x7f589a05, 0xc73b7cfd), TOBN(0xf544607d, 0x880d6d28)}},
+ {{TOBN(0x17ba93b1, 0xa20ef103), TOBN(0xad859130, 0x6ba6577b),
+ TOBN(0x65c91cf6, 0x6fa214a0), TOBN(0xd7d49c6c, 0x27990da5)},
+ {TOBN(0xecd9ec8d, 0x20bb569d), TOBN(0xbd4b2502, 0xeeffbc33),
+ TOBN(0x2056ca5a, 0x6bed0467), TOBN(0x7916a1f7, 0x5b63728c)}},
+ {{TOBN(0xd4f9497d, 0x53a4f566), TOBN(0x89734664, 0x97b56810),
+ TOBN(0xf8e1da74, 0x0494a621), TOBN(0x82546a93, 0x8d011c68)},
+ {TOBN(0x1f3acb19, 0xc61ac162), TOBN(0x52f8fa9c, 0xabad0d3e),
+ TOBN(0x15356523, 0xb4b7ea43), TOBN(0x5a16ad61, 0xae608125)}},
+ {{TOBN(0xb0bcb87f, 0x4faed184), TOBN(0x5f236b1d, 0x5029f45f),
+ TOBN(0xd42c7607, 0x0bc6b1fc), TOBN(0xc644324e, 0x68aefce3)},
+ {TOBN(0x8e191d59, 0x5c5d8446), TOBN(0xc0208077, 0x13ae1979),
+ TOBN(0xadcaee55, 0x3ba59cc7), TOBN(0x20ed6d6b, 0xa2cb81ba)}},
+ {{TOBN(0x0952ba19, 0xb6efcffc), TOBN(0x60f12d68, 0x97c0b87c),
+ TOBN(0x4ee2c7c4, 0x9caa30bc), TOBN(0x767238b7, 0x97fbff4e)},
+ {TOBN(0xebc73921, 0x501b5d92), TOBN(0x3279e3df, 0xc2a37737),
+ TOBN(0x9fc12bc8, 0x6d197543), TOBN(0xfa94dc6f, 0x0a40db4e)}},
+ {{TOBN(0x7392b41a, 0x530ccbbd), TOBN(0x87c82146, 0xea823525),
+ TOBN(0xa52f984c, 0x05d98d0c), TOBN(0x2ae57d73, 0x5ef6974c)},
+ {TOBN(0x9377f7bf, 0x3042a6dd), TOBN(0xb1a007c0, 0x19647a64),
+ TOBN(0xfaa9079a, 0x0cca9767), TOBN(0x3d81a25b, 0xf68f72d5)}},
+ {{TOBN(0x752067f8, 0xff81578e), TOBN(0x78622150, 0x9045447d),
+ TOBN(0xc0c22fcf, 0x0505aa6f), TOBN(0x1030f0a6, 0x6bed1c77)},
+ {TOBN(0x31f29f15, 0x1f0bd739), TOBN(0x2d7989c7, 0xe6debe85),
+ TOBN(0x5c070e72, 0x8e677e98), TOBN(0x0a817bd3, 0x06e81fd5)}},
+ {{TOBN(0xc110d830, 0xb0f2ac95), TOBN(0x48d0995a, 0xab20e64e),
+ TOBN(0x0f3e00e1, 0x7729cd9a), TOBN(0x2a570c20, 0xdd556946)},
+ {TOBN(0x912dbcfd, 0x4e86214d), TOBN(0x2d014ee2, 0xcf615498),
+ TOBN(0x55e2b1e6, 0x3530d76e), TOBN(0xc5135ae4, 0xfd0fd6d1)}},
+ {{TOBN(0x0066273a, 0xd4f3049f), TOBN(0xbb8e9893, 0xe7087477),
+ TOBN(0x2dba1ddb, 0x14c6e5fd), TOBN(0xdba37886, 0x51f57e6c)},
+ {TOBN(0x5aaee0a6, 0x5a72f2cf), TOBN(0x1208bfbf, 0x7bea5642),
+ TOBN(0xf5c6aa3b, 0x67872c37), TOBN(0xd726e083, 0x43f93224)}},
+ {{TOBN(0x1854daa5, 0x061f1658), TOBN(0xc0016df1, 0xdf0cd2b3),
+ TOBN(0xc2a3f23e, 0x833d50de), TOBN(0x73b681d2, 0xbbbd3017)},
+ {TOBN(0x2f046dc4, 0x3ac343c0), TOBN(0x9c847e7d, 0x85716421),
+ TOBN(0xe1e13c91, 0x0917eed4), TOBN(0x3fc9eebd, 0x63a1b9c6)}},
+ {{TOBN(0x0f816a72, 0x7fe02299), TOBN(0x6335ccc2, 0x294f3319),
+ TOBN(0x3820179f, 0x4745c5be), TOBN(0xe647b782, 0x922f066e)},
+ {TOBN(0xc22e49de, 0x02cafb8a), TOBN(0x299bc2ff, 0xfcc2eccc),
+ TOBN(0x9a8feea2, 0x6e0e8282), TOBN(0xa627278b, 0xfe893205)}},
+ {{TOBN(0xa7e19733, 0x7933e47b), TOBN(0xf4ff6b13, 0x2e766402),
+ TOBN(0xa4d8be0a, 0x98440d9f), TOBN(0x658f5c2f, 0x38938808)},
+ {TOBN(0x90b75677, 0xc95b3b3e), TOBN(0xfa044269, 0x3137b6ff),
+ TOBN(0x077b039b, 0x43c47c29), TOBN(0xcca95dd3, 0x8a6445b2)}},
+ {{TOBN(0x0b498ba4, 0x2333fc4c), TOBN(0x274f8e68, 0xf736a1b1),
+ TOBN(0x6ca348fd, 0x5f1d4b2e), TOBN(0x24d3be78, 0xa8f10199)},
+ {TOBN(0x8535f858, 0xca14f530), TOBN(0xa6e7f163, 0x5b982e51),
+ TOBN(0x847c8512, 0x36e1bf62), TOBN(0xf6a7c58e, 0x03448418)}},
+ {{TOBN(0x583f3703, 0xf9374ab6), TOBN(0x864f9195, 0x6e564145),
+ TOBN(0x33bc3f48, 0x22526d50), TOBN(0x9f323c80, 0x1262a496)},
+ {TOBN(0xaa97a7ae, 0x3f046a9a), TOBN(0x70da183e, 0xdf8a039a),
+ TOBN(0x5b68f71c, 0x52aa0ba6), TOBN(0x9be0fe51, 0x21459c2d)}},
+ {{TOBN(0xc1e17eb6, 0xcbc613e5), TOBN(0x33131d55, 0x497ea61c),
+ TOBN(0x2f69d39e, 0xaf7eded5), TOBN(0x73c2f434, 0xde6af11b)},
+ {TOBN(0x4ca52493, 0xa4a375fa), TOBN(0x5f06787c, 0xb833c5c2),
+ TOBN(0x814e091f, 0x3e6e71cf), TOBN(0x76451f57, 0x8b746666)}}},
+ {{{TOBN(0x80f9bdef, 0x694db7e0), TOBN(0xedca8787, 0xb9fcddc6),
+ TOBN(0x51981c34, 0x03b8dce1), TOBN(0x4274dcf1, 0x70e10ba1)},
+ {TOBN(0xf72743b8, 0x6def6d1a), TOBN(0xd25b1670, 0xebdb1866),
+ TOBN(0xc4491e8c, 0x050c6f58), TOBN(0x2be2b2ab, 0x87fbd7f5)}},
+ {{TOBN(0x3e0e5c9d, 0xd111f8ec), TOBN(0xbcc33f8d, 0xb7c4e760),
+ TOBN(0x702f9a91, 0xbd392a51), TOBN(0x7da4a795, 0xc132e92d)},
+ {TOBN(0x1a0b0ae3, 0x0bb1151b), TOBN(0x54febac8, 0x02e32251),
+ TOBN(0xea3a5082, 0x694e9e78), TOBN(0xe58ffec1, 0xe4fe40b8)}},
+ {{TOBN(0xf85592fc, 0xd1e0cf9e), TOBN(0xdea75f0d, 0xc0e7b2e8),
+ TOBN(0xc04215cf, 0xc135584e), TOBN(0x174fc727, 0x2f57092a)},
+ {TOBN(0xe7277877, 0xeb930bea), TOBN(0x504caccb, 0x5eb02a5a),
+ TOBN(0xf9fe08f7, 0xf5241b9b), TOBN(0xe7fb62f4, 0x8d5ca954)}},
+ {{TOBN(0xfbb8349d, 0x29c4120b), TOBN(0x9f94391f, 0xc0d0d915),
+ TOBN(0xc4074fa7, 0x5410ba51), TOBN(0xa66adbf6, 0x150a5911)},
+ {TOBN(0xc164543c, 0x34bfca38), TOBN(0xe0f27560, 0xb9e1ccfc),
+ TOBN(0x99da0f53, 0xe820219c), TOBN(0xe8234498, 0xc6b4997a)}},
+ {{TOBN(0xcfb88b76, 0x9d4c5423), TOBN(0x9e56eb10, 0xb0521c49),
+ TOBN(0x418e0b5e, 0xbe8700a1), TOBN(0x00cbaad6, 0xf93cb58a)},
+ {TOBN(0xe923fbde, 0xd92a5e67), TOBN(0xca4979ac, 0x1f347f11),
+ TOBN(0x89162d85, 0x6bc0585b), TOBN(0xdd6254af, 0xac3c70e3)}},
+ {{TOBN(0x7b23c513, 0x516e19e4), TOBN(0x56e2e847, 0xc5c4d593),
+ TOBN(0x9f727d73, 0x5ce71ef6), TOBN(0x5b6304a6, 0xf79a44c5)},
+ {TOBN(0x6638a736, 0x3ab7e433), TOBN(0x1adea470, 0xfe742f83),
+ TOBN(0xe054b854, 0x5b7fc19f), TOBN(0xf935381a, 0xba1d0698)}},
+ {{TOBN(0x546eab2d, 0x799e9a74), TOBN(0x96239e0e, 0xa949f729),
+ TOBN(0xca274c6b, 0x7090055a), TOBN(0x835142c3, 0x9020c9b0)},
+ {TOBN(0xa405667a, 0xa2e8807f), TOBN(0x29f2c085, 0x1aa3d39e),
+ TOBN(0xcc555d64, 0x42fc72f5), TOBN(0xe856e0e7, 0xfbeacb3c)}},
+ {{TOBN(0xb5504f9d, 0x918e4936), TOBN(0x65035ef6, 0xb2513982),
+ TOBN(0x0553a0c2, 0x6f4d9cb9), TOBN(0x6cb10d56, 0xbea85509)},
+ {TOBN(0x48d957b7, 0xa242da11), TOBN(0x16a4d3dd, 0x672b7268),
+ TOBN(0x3d7e637c, 0x8502a96b), TOBN(0x27c7032b, 0x730d463b)}},
+ {{TOBN(0xbdc02b18, 0xe4136a14), TOBN(0xbacf969d, 0x678e32bf),
+ TOBN(0xc98d89a3, 0xdd9c3c03), TOBN(0x7b92420a, 0x23becc4f)},
+ {TOBN(0xd4b41f78, 0xc64d565c), TOBN(0x9f969d00, 0x10f28295),
+ TOBN(0xec7f7f76, 0xb13d051a), TOBN(0x08945e1e, 0xa92da585)}},
+ {{TOBN(0x55366b7d, 0x5846426f), TOBN(0xe7d09e89, 0x247d441d),
+ TOBN(0x510b404d, 0x736fbf48), TOBN(0x7fa003d0, 0xe784bd7d)},
+ {TOBN(0x25f7614f, 0x17fd9596), TOBN(0x49e0e0a1, 0x35cb98db),
+ TOBN(0x2c65957b, 0x2e83a76a), TOBN(0x5d40da8d, 0xcddbe0f8)}},
+ {{TOBN(0xf2b8c405, 0x050bad24), TOBN(0x8918426d, 0xc2aa4823),
+ TOBN(0x2aeab3dd, 0xa38365a7), TOBN(0x72031717, 0x7c91b690)},
+ {TOBN(0x8b00d699, 0x60a94120), TOBN(0x478a255d, 0xe99eaeec),
+ TOBN(0xbf656a5f, 0x6f60aafd), TOBN(0xdfd7cb75, 0x5dee77b3)}},
+ {{TOBN(0x37f68bb4, 0xa595939d), TOBN(0x03556479, 0x28740217),
+ TOBN(0x8e740e7c, 0x84ad7612), TOBN(0xd89bc843, 0x9044695f)},
+ {TOBN(0xf7f3da5d, 0x85a9184d), TOBN(0x562563bb, 0x9fc0b074),
+ TOBN(0x06d2e6aa, 0xf88a888e), TOBN(0x612d8643, 0x161fbe7c)}},
+ {{TOBN(0x465edba7, 0xf64085e7), TOBN(0xb230f304, 0x29aa8511),
+ TOBN(0x53388426, 0xcda2d188), TOBN(0x90885735, 0x4b666649)},
+ {TOBN(0x6f02ff9a, 0x652f54f6), TOBN(0x65c82294, 0x5fae2bf0),
+ TOBN(0x7816ade0, 0x62f5eee3), TOBN(0xdcdbdf43, 0xfcc56d70)}},
+ {{TOBN(0x9fb3bba3, 0x54530bb2), TOBN(0xbde3ef77, 0xcb0869ea),
+ TOBN(0x89bc9046, 0x0b431163), TOBN(0x4d03d7d2, 0xe4819a35)},
+ {TOBN(0x33ae4f9e, 0x43b6a782), TOBN(0x216db307, 0x9c88a686),
+ TOBN(0x91dd88e0, 0x00ffedd9), TOBN(0xb280da9f, 0x12bd4840)}},
+ {{TOBN(0x32a7cb8a, 0x1635e741), TOBN(0xfe14008a, 0x78be02a7),
+ TOBN(0x3fafb334, 0x1b7ae030), TOBN(0x7fd508e7, 0x5add0ce9)},
+ {TOBN(0x72c83219, 0xd607ad51), TOBN(0x0f229c0a, 0x8d40964a),
+ TOBN(0x1be2c336, 0x1c878da2), TOBN(0xe0c96742, 0xeab2ab86)}},
+ {{TOBN(0x458f8691, 0x3e538cd7), TOBN(0xa7001f6c, 0x8e08ad53),
+ TOBN(0x52b8c6e6, 0xbf5d15ff), TOBN(0x548234a4, 0x011215dd)},
+ {TOBN(0xff5a9d2d, 0x3d5b4045), TOBN(0xb0ffeeb6, 0x4a904190),
+ TOBN(0x55a3aca4, 0x48607f8b), TOBN(0x8cbd665c, 0x30a0672a)}},
+ {{TOBN(0x87f834e0, 0x42583068), TOBN(0x02da2aeb, 0xf3f6e683),
+ TOBN(0x6b763e5d, 0x05c12248), TOBN(0x7230378f, 0x65a8aefc)},
+ {TOBN(0x93bd80b5, 0x71e8e5ca), TOBN(0x53ab041c, 0xb3b62524),
+ TOBN(0x1b860513, 0x6c9c552e), TOBN(0xe84d402c, 0xd5524e66)}},
+ {{TOBN(0xa37f3573, 0xf37f5937), TOBN(0xeb0f6c7d, 0xd1e4fca5),
+ TOBN(0x2965a554, 0xac8ab0fc), TOBN(0x17fbf56c, 0x274676ac)},
+ {TOBN(0x2e2f6bd9, 0xacf7d720), TOBN(0x41fc8f88, 0x10224766),
+ TOBN(0x517a14b3, 0x85d53bef), TOBN(0xdae327a5, 0x7d76a7d1)}},
+ {{TOBN(0x6ad0a065, 0xc4818267), TOBN(0x33aa189b, 0x37c1bbc1),
+ TOBN(0x64970b52, 0x27392a92), TOBN(0x21699a1c, 0x2d1535ea)},
+ {TOBN(0xcd20779c, 0xc2d7a7fd), TOBN(0xe3186059, 0x99c83cf2),
+ TOBN(0x9b69440b, 0x72c0b8c7), TOBN(0xa81497d7, 0x7b9e0e4d)}},
+ {{TOBN(0x515d5c89, 0x1f5f82dc), TOBN(0x9a7f67d7, 0x6361079e),
+ TOBN(0xa8da81e3, 0x11a35330), TOBN(0xe44990c4, 0x4b18be1b)},
+ {TOBN(0xc7d5ed95, 0xaf103e59), TOBN(0xece8aba7, 0x8dac9261),
+ TOBN(0xbe82b099, 0x9394b8d3), TOBN(0x6830f09a, 0x16adfe83)}},
+ {{TOBN(0x250a29b4, 0x88172d01), TOBN(0x8b20bd65, 0xcaff9e02),
+ TOBN(0xb8a7661e, 0xe8a6329a), TOBN(0x4520304d, 0xd3fce920)},
+ {TOBN(0xae45da1f, 0x2b47f7ef), TOBN(0xe07f5288, 0x5bffc540),
+ TOBN(0xf7997009, 0x3464f874), TOBN(0x2244c2cd, 0xa6fa1f38)}},
+ {{TOBN(0x43c41ac1, 0x94d7d9b1), TOBN(0x5bafdd82, 0xc82e7f17),
+ TOBN(0xdf0614c1, 0x5fda0fca), TOBN(0x74b043a7, 0xa8ae37ad)},
+ {TOBN(0x3ba6afa1, 0x9e71734c), TOBN(0x15d5437e, 0x9c450f2e),
+ TOBN(0x4a5883fe, 0x67e242b1), TOBN(0x5143bdc2, 0x2c1953c2)}},
+ {{TOBN(0x542b8b53, 0xfc5e8920), TOBN(0x363bf9a8, 0x9a9cee08),
+ TOBN(0x02375f10, 0xc3486e08), TOBN(0x2037543b, 0x8c5e70d2)},
+ {TOBN(0x7109bccc, 0x625640b4), TOBN(0xcbc1051e, 0x8bc62c3b),
+ TOBN(0xf8455fed, 0x803f26ea), TOBN(0x6badceab, 0xeb372424)}},
+ {{TOBN(0xa2a9ce7c, 0x6b53f5f9), TOBN(0x64246595, 0x1b176d99),
+ TOBN(0xb1298d36, 0xb95c081b), TOBN(0x53505bb8, 0x1d9a9ee6)},
+ {TOBN(0x3f6f9e61, 0xf2ba70b0), TOBN(0xd07e16c9, 0x8afad453),
+ TOBN(0x9f1694bb, 0xe7eb4a6a), TOBN(0xdfebced9, 0x3cb0bc8e)}},
+ {{TOBN(0x92d3dcdc, 0x53868c8b), TOBN(0x174311a2, 0x386107a6),
+ TOBN(0x4109e07c, 0x689b4e64), TOBN(0x30e4587f, 0x2df3dcb6)},
+ {TOBN(0x841aea31, 0x0811b3b2), TOBN(0x6144d41d, 0x0cce43ea),
+ TOBN(0x464c4581, 0x2a9a7803), TOBN(0xd03d371f, 0x3e158930)}},
+ {{TOBN(0xc676d7f2, 0xb1f3390b), TOBN(0x9f7a1b8c, 0xa5b61272),
+ TOBN(0x4ebebfc9, 0xc2e127a9), TOBN(0x4602500c, 0x5dd997bf)},
+ {TOBN(0x7f09771c, 0x4711230f), TOBN(0x058eb37c, 0x020f09c1),
+ TOBN(0xab693d4b, 0xfee5e38b), TOBN(0x9289eb1f, 0x4653cbc0)}},
+ {{TOBN(0xbecf46ab, 0xd51b9cf5), TOBN(0xd2aa9c02, 0x9f0121af),
+ TOBN(0x36aaf7d2, 0xe90dc274), TOBN(0x909e4ea0, 0x48b95a3c)},
+ {TOBN(0xe6b70496, 0x6f32dbdb), TOBN(0x672188a0, 0x8b030b3e),
+ TOBN(0xeeffe5b3, 0xcfb617e2), TOBN(0x87e947de, 0x7c82709e)}},
+ {{TOBN(0xa44d2b39, 0x1770f5a7), TOBN(0xe4d4d791, 0x0e44eb82),
+ TOBN(0x42e69d1e, 0x3f69712a), TOBN(0xbf11c4d6, 0xac6a820e)},
+ {TOBN(0xb5e7f3e5, 0x42c4224c), TOBN(0xd6b4e81c, 0x449d941c),
+ TOBN(0x5d72bd16, 0x5450e878), TOBN(0x6a61e28a, 0xee25ac54)}},
+ {{TOBN(0x33272094, 0xe6f1cd95), TOBN(0x7512f30d, 0x0d18673f),
+ TOBN(0x32f7a4ca, 0x5afc1464), TOBN(0x2f095656, 0x6bbb977b)},
+ {TOBN(0x586f47ca, 0xa8226200), TOBN(0x02c868ad, 0x1ac07369),
+ TOBN(0x4ef2b845, 0xc613acbe), TOBN(0x43d7563e, 0x0386054c)}},
+ {{TOBN(0x54da9dc7, 0xab952578), TOBN(0xb5423df2, 0x26e84d0b),
+ TOBN(0xa8b64eeb, 0x9b872042), TOBN(0xac205782, 0x5990f6df)},
+ {TOBN(0x4ff696eb, 0x21f4c77a), TOBN(0x1a79c3e4, 0xaab273af),
+ TOBN(0x29bc922e, 0x9436b3f1), TOBN(0xff807ef8, 0xd6d9a27a)}},
+ {{TOBN(0x82acea3d, 0x778f22a0), TOBN(0xfb10b2e8, 0x5b5e7469),
+ TOBN(0xc0b16980, 0x2818ee7d), TOBN(0x011afff4, 0xc91c1a2f)},
+ {TOBN(0x95a6d126, 0xad124418), TOBN(0x31c081a5, 0xe72e295f),
+ TOBN(0x36bb283a, 0xf2f4db75), TOBN(0xd115540f, 0x7acef462)}},
+ {{TOBN(0xc7f3a8f8, 0x33f6746c), TOBN(0x21e46f65, 0xfea990ca),
+ TOBN(0x915fd5c5, 0xcaddb0a9), TOBN(0xbd41f016, 0x78614555)},
+ {TOBN(0x346f4434, 0x426ffb58), TOBN(0x80559436, 0x14dbc204),
+ TOBN(0xf3dd20fe, 0x5a969b7f), TOBN(0x9d59e956, 0xe899a39a)}},
+ {{TOBN(0xf1b0971c, 0x8ad4cf4b), TOBN(0x03448860, 0x2ffb8fb8),
+ TOBN(0xf071ac3c, 0x65340ba4), TOBN(0x408d0596, 0xb27fd758)},
+ {TOBN(0xe7c78ea4, 0x98c364b0), TOBN(0xa4aac4a5, 0x051e8ab5),
+ TOBN(0xb9e1d560, 0x485d9002), TOBN(0x9acd518a, 0x88844455)}},
+ {{TOBN(0xe4ca688f, 0xd06f56c0), TOBN(0xa48af70d, 0xdf027972),
+ TOBN(0x691f0f04, 0x5e9a609d), TOBN(0xa9dd82cd, 0xee61270e)},
+ {TOBN(0x8903ca63, 0xa0ef18d3), TOBN(0x9fb7ee35, 0x3d6ca3bd),
+ TOBN(0xa7b4a09c, 0xabf47d03), TOBN(0x4cdada01, 0x1c67de8e)}},
+ {{TOBN(0x52003749, 0x9355a244), TOBN(0xe77fd2b6, 0x4f2151a9),
+ TOBN(0x695d6cf6, 0x66b4efcb), TOBN(0xc5a0cacf, 0xda2cfe25)},
+ {TOBN(0x104efe5c, 0xef811865), TOBN(0xf52813e8, 0x9ea5cc3d),
+ TOBN(0x855683dc, 0x40b58dbc), TOBN(0x0338ecde, 0x175fcb11)}},
+ {{TOBN(0xf9a05637, 0x74921592), TOBN(0xb4f1261d, 0xb9bb9d31),
+ TOBN(0x551429b7, 0x4e9c5459), TOBN(0xbe182e6f, 0x6ea71f53)},
+ {TOBN(0xd3a3b07c, 0xdfc50573), TOBN(0x9ba1afda, 0x62be8d44),
+ TOBN(0x9bcfd2cb, 0x52ab65d3), TOBN(0xdf11d547, 0xa9571802)}},
+ {{TOBN(0x099403ee, 0x02a2404a), TOBN(0x497406f4, 0x21088a71),
+ TOBN(0x99479409, 0x5004ae71), TOBN(0xbdb42078, 0xa812c362)},
+ {TOBN(0x2b72a30f, 0xd8828442), TOBN(0x283add27, 0xfcb5ed1c),
+ TOBN(0xf7c0e200, 0x66a40015), TOBN(0x3e3be641, 0x08b295ef)}},
+ {{TOBN(0xac127dc1, 0xe038a675), TOBN(0x729deff3, 0x8c5c6320),
+ TOBN(0xb7df8fd4, 0xa90d2c53), TOBN(0x9b74b0ec, 0x681e7cd3)},
+ {TOBN(0x5cb5a623, 0xdab407e5), TOBN(0xcdbd3615, 0x76b340c6),
+ TOBN(0xa184415a, 0x7d28392c), TOBN(0xc184c1d8, 0xe96f7830)}},
+ {{TOBN(0xc3204f19, 0x81d3a80f), TOBN(0xfde0c841, 0xc8e02432),
+ TOBN(0x78203b3e, 0x8149e0c1), TOBN(0x5904bdbb, 0x08053a73)},
+ {TOBN(0x30fc1dd1, 0x101b6805), TOBN(0x43c223bc, 0x49aa6d49),
+ TOBN(0x9ed67141, 0x7a174087), TOBN(0x311469a0, 0xd5997008)}},
+ {{TOBN(0xb189b684, 0x5e43fc61), TOBN(0xf3282375, 0xe0d3ab57),
+ TOBN(0x4fa34b67, 0xb1181da8), TOBN(0x621ed0b2, 0x99ee52b8)},
+ {TOBN(0x9b178de1, 0xad990676), TOBN(0xd51de67b, 0x56d54065),
+ TOBN(0x2a2c27c4, 0x7538c201), TOBN(0x33856ec8, 0x38a40f5c)}},
+ {{TOBN(0x2522fc15, 0xbe6cdcde), TOBN(0x1e603f33, 0x9f0c6f89),
+ TOBN(0x7994edc3, 0x103e30a6), TOBN(0x033a00db, 0x220c853e)},
+ {TOBN(0xd3cfa409, 0xf7bb7fd7), TOBN(0x70f8781e, 0x462d18f6),
+ TOBN(0xbbd82980, 0x687fe295), TOBN(0x6eef4c32, 0x595669f3)}},
+ {{TOBN(0x86a9303b, 0x2f7e85c3), TOBN(0x5fce4621, 0x71988f9b),
+ TOBN(0x5b935bf6, 0xc138acb5), TOBN(0x30ea7d67, 0x25661212)},
+ {TOBN(0xef1eb5f4, 0xe51ab9a2), TOBN(0x0587c98a, 0xae067c78),
+ TOBN(0xb3ce1b3c, 0x77ca9ca6), TOBN(0x2a553d4d, 0x54b5f057)}},
+ {{TOBN(0xc7898236, 0x4da29ec2), TOBN(0xdbdd5d13, 0xb9c57316),
+ TOBN(0xc57d6e6b, 0x2cd80d47), TOBN(0x80b460cf, 0xfe9e7391)},
+ {TOBN(0x98648cab, 0xf963c31e), TOBN(0x67f9f633, 0xcc4d32fd),
+ TOBN(0x0af42a9d, 0xfdf7c687), TOBN(0x55f292a3, 0x0b015ea7)}},
+ {{TOBN(0x89e468b2, 0xcd21ab3d), TOBN(0xe504f022, 0xc393d392),
+ TOBN(0xab21e1d4, 0xa5013af9), TOBN(0xe3283f78, 0xc2c28acb)},
+ {TOBN(0xf38b35f6, 0x226bf99f), TOBN(0xe8354274, 0x0e291e69),
+ TOBN(0x61673a15, 0xb20c162d), TOBN(0xc101dc75, 0xb04fbdbe)}},
+ {{TOBN(0x8323b4c2, 0x255bd617), TOBN(0x6c969693, 0x6c2a9154),
+ TOBN(0xc6e65860, 0x62679387), TOBN(0x8e01db0c, 0xb8c88e23)},
+ {TOBN(0x33c42873, 0x893a5559), TOBN(0x7630f04b, 0x47a3e149),
+ TOBN(0xb5d80805, 0xddcf35f8), TOBN(0x582ca080, 0x77dfe732)}},
+ {{TOBN(0x2c7156e1, 0x0b1894a0), TOBN(0x92034001, 0xd81c68c0),
+ TOBN(0xed225d00, 0xc8b115b5), TOBN(0x237f9c22, 0x83b907f2)},
+ {TOBN(0x0ea2f32f, 0x4470e2c0), TOBN(0xb725f7c1, 0x58be4e95),
+ TOBN(0x0f1dcafa, 0xb1ae5463), TOBN(0x59ed5187, 0x1ba2fc04)}},
+ {{TOBN(0xf6e0f316, 0xd0115d4d), TOBN(0x5180b12f, 0xd3691599),
+ TOBN(0x157e32c9, 0x527f0a41), TOBN(0x7b0b081d, 0xa8e0ecc0)},
+ {TOBN(0x6dbaaa8a, 0xbf4f0dd0), TOBN(0x99b289c7, 0x4d252696),
+ TOBN(0x79b7755e, 0xdbf864fe), TOBN(0x6974e2b1, 0x76cad3ab)}},
+ {{TOBN(0x35dbbee2, 0x06ddd657), TOBN(0xe7cbdd11, 0x2ff3a96d),
+ TOBN(0x88381968, 0x076be758), TOBN(0x2d737e72, 0x08c91f5d)},
+ {TOBN(0x5f83ab62, 0x86ec3776), TOBN(0x98aa649d, 0x945fa7a1),
+ TOBN(0xf477ec37, 0x72ef0933), TOBN(0x66f52b1e, 0x098c17b1)}},
+ {{TOBN(0x9eec58fb, 0xd803738b), TOBN(0x91aaade7, 0xe4e86aa4),
+ TOBN(0x6b1ae617, 0xa5b51492), TOBN(0x63272121, 0xbbc45974)},
+ {TOBN(0x7e0e28f0, 0x862c5129), TOBN(0x0a8f79a9, 0x3321a4a0),
+ TOBN(0xe26d1664, 0x5041c88f), TOBN(0x0571b805, 0x53233e3a)}},
+ {{TOBN(0xd1b0ccde, 0xc9520711), TOBN(0x55a9e4ed, 0x3c8b84bf),
+ TOBN(0x9426bd39, 0xa1fef314), TOBN(0x4f5f638e, 0x6eb93f2b)},
+ {TOBN(0xba2a1ed3, 0x2bf9341b), TOBN(0xd63c1321, 0x4d42d5a9),
+ TOBN(0xd2964a89, 0x316dc7c5), TOBN(0xd1759606, 0xca511851)}},
+ {{TOBN(0xd8a9201f, 0xf9e6ed35), TOBN(0xb7b5ee45, 0x6736925a),
+ TOBN(0x0a83fbbc, 0x99581af7), TOBN(0x3076bc40, 0x64eeb051)},
+ {TOBN(0x5511c98c, 0x02dec312), TOBN(0x270de898, 0x238dcb78),
+ TOBN(0x2cf4cf9c, 0x539c08c9), TOBN(0xa70cb65e, 0x38d3b06e)}},
+ {{TOBN(0xb12ec10e, 0xcfe57bbd), TOBN(0x82c7b656, 0x35a0c2b5),
+ TOBN(0xddc7d5cd, 0x161c67bd), TOBN(0xe32e8985, 0xae3a32cc)},
+ {TOBN(0x7aba9444, 0xd11a5529), TOBN(0xe964ed02, 0x2427fa1a),
+ TOBN(0x1528392d, 0x24a1770a), TOBN(0xa152ce2c, 0x12c72fcd)}},
+ {{TOBN(0x714553a4, 0x8ec07649), TOBN(0x18b4c290, 0x459dd453),
+ TOBN(0xea32b714, 0x7b64b110), TOBN(0xb871bfa5, 0x2e6f07a2)},
+ {TOBN(0xb67112e5, 0x9e2e3c9b), TOBN(0xfbf250e5, 0x44aa90f6),
+ TOBN(0xf77aedb8, 0xbd539006), TOBN(0x3b0cdf9a, 0xd172a66f)}},
+ {{TOBN(0xedf69fea, 0xf8c51187), TOBN(0x05bb67ec, 0x741e4da7),
+ TOBN(0x47df0f32, 0x08114345), TOBN(0x56facb07, 0xbb9792b1)},
+ {TOBN(0xf3e007e9, 0x8f6229e4), TOBN(0x62d103f4, 0x526fba0f),
+ TOBN(0x4f33bef7, 0xb0339d79), TOBN(0x9841357b, 0xb59bfec1)}},
+ {{TOBN(0xfa8dbb59, 0xc34e6705), TOBN(0xc3c7180b, 0x7fdaa84c),
+ TOBN(0xf95872fc, 0xa4108537), TOBN(0x8750cc3b, 0x932a3e5a)},
+ {TOBN(0xb61cc69d, 0xb7275d7d), TOBN(0xffa0168b, 0x2e59b2e9),
+ TOBN(0xca032abc, 0x6ecbb493), TOBN(0x1d86dbd3, 0x2c9082d8)}},
+ {{TOBN(0xae1e0b67, 0xe28ef5ba), TOBN(0x2c9a4699, 0xcb18e169),
+ TOBN(0x0ecd0e33, 0x1e6bbd20), TOBN(0x571b360e, 0xaf5e81d2)},
+ {TOBN(0xcd9fea58, 0x101c1d45), TOBN(0x6651788e, 0x18880452),
+ TOBN(0xa9972635, 0x1f8dd446), TOBN(0x44bed022, 0xe37281d0)}},
+ {{TOBN(0x094b2b2d, 0x33da525d), TOBN(0xf193678e, 0x13144fd8),
+ TOBN(0xb8ab5ba4, 0xf4c1061d), TOBN(0x4343b5fa, 0xdccbe0f4)},
+ {TOBN(0xa8702371, 0x63812713), TOBN(0x47bf6d2d, 0xf7611d93),
+ TOBN(0x46729b8c, 0xbd21e1d7), TOBN(0x7484d4e0, 0xd629e77d)}},
+ {{TOBN(0x830e6eea, 0x60dbac1f), TOBN(0x23d8c484, 0xda06a2f7),
+ TOBN(0x896714b0, 0x50ca535b), TOBN(0xdc8d3644, 0xebd97a9b)},
+ {TOBN(0x106ef9fa, 0xb12177b4), TOBN(0xf79bf464, 0x534d5d9c),
+ TOBN(0x2537a349, 0xa6ab360b), TOBN(0xc7c54253, 0xa00c744f)}},
+ {{TOBN(0xb3c7a047, 0xe5911a76), TOBN(0x61ffa5c8, 0x647f1ee7),
+ TOBN(0x15aed36f, 0x8f56ab42), TOBN(0x6a0d41b0, 0xa3ff9ac9)},
+ {TOBN(0x68f469f5, 0xcc30d357), TOBN(0xbe9adf81, 0x6b72be96),
+ TOBN(0x1cd926fe, 0x903ad461), TOBN(0x7e89e38f, 0xcaca441b)}},
+ {{TOBN(0xf0f82de5, 0xfacf69d4), TOBN(0x363b7e76, 0x4775344c),
+ TOBN(0x6894f312, 0xb2e36d04), TOBN(0x3c6cb4fe, 0x11d1c9a5)},
+ {TOBN(0x85d9c339, 0x4008e1f2), TOBN(0x5e9a85ea, 0x249f326c),
+ TOBN(0xdc35c60a, 0x678c5e06), TOBN(0xc08b944f, 0x9f86fba9)}},
+ {{TOBN(0xde40c02c, 0x89f71f0f), TOBN(0xad8f3e31, 0xff3da3c0),
+ TOBN(0x3ea5096b, 0x42125ded), TOBN(0x13879cbf, 0xa7379183)},
+ {TOBN(0x6f4714a5, 0x6b306a0b), TOBN(0x359c2ea6, 0x67646c5e),
+ TOBN(0xfacf8943, 0x07726368), TOBN(0x07a58935, 0x65ff431e)}},
+ {{TOBN(0x24d661d1, 0x68754ab0), TOBN(0x801fce1d, 0x6f429a76),
+ TOBN(0xc068a85f, 0xa58ce769), TOBN(0xedc35c54, 0x5d5eca2b)},
+ {TOBN(0xea31276f, 0xa3f660d1), TOBN(0xa0184ebe, 0xb8fc7167),
+ TOBN(0x0f20f21a, 0x1d8db0ae), TOBN(0xd96d095f, 0x56c35e12)}},
+ {{TOBN(0xedf402b5, 0xf8c2a25b), TOBN(0x1bb772b9, 0x059204b6),
+ TOBN(0x50cbeae2, 0x19b4e34c), TOBN(0x93109d80, 0x3fa0845a)},
+ {TOBN(0x54f7ccf7, 0x8ef59fb5), TOBN(0x3b438fe2, 0x88070963),
+ TOBN(0x9e28c659, 0x31f3ba9b), TOBN(0x9cc31b46, 0xead9da92)}},
+ {{TOBN(0x3c2f0ba9, 0xb733aa5f), TOBN(0xdece47cb, 0xf05af235),
+ TOBN(0xf8e3f715, 0xa2ac82a5), TOBN(0xc97ba641, 0x2203f18a)},
+ {TOBN(0xc3af5504, 0x09c11060), TOBN(0x56ea2c05, 0x46af512d),
+ TOBN(0xfac28daf, 0xf3f28146), TOBN(0x87fab43a, 0x959ef494)}}},
+ {{{TOBN(0x09891641, 0xd4c5105f), TOBN(0x1ae80f8e, 0x6d7fbd65),
+ TOBN(0x9d67225f, 0xbee6bdb0), TOBN(0x3b433b59, 0x7fc4d860)},
+ {TOBN(0x44e66db6, 0x93e85638), TOBN(0xf7b59252, 0xe3e9862f),
+ TOBN(0xdb785157, 0x665c32ec), TOBN(0x702fefd7, 0xae362f50)}},
+ {{TOBN(0x3754475d, 0x0fefb0c3), TOBN(0xd48fb56b, 0x46d7c35d),
+ TOBN(0xa070b633, 0x363798a4), TOBN(0xae89f3d2, 0x8fdb98e6)},
+ {TOBN(0x970b89c8, 0x6363d14c), TOBN(0x89817521, 0x67abd27d),
+ TOBN(0x9bf7d474, 0x44d5a021), TOBN(0xb3083baf, 0xcac72aee)}},
+ {{TOBN(0x389741de, 0xbe949a44), TOBN(0x638e9388, 0x546a4fa5),
+ TOBN(0x3fe6419c, 0xa0047bdc), TOBN(0x7047f648, 0xaaea57ca)},
+ {TOBN(0x54e48a90, 0x41fbab17), TOBN(0xda8e0b28, 0x576bdba2),
+ TOBN(0xe807eebc, 0xc72afddc), TOBN(0x07d3336d, 0xf42577bf)}},
+ {{TOBN(0x62a8c244, 0xbfe20925), TOBN(0x91c19ac3, 0x8fdce867),
+ TOBN(0x5a96a5d5, 0xdd387063), TOBN(0x61d587d4, 0x21d324f6)},
+ {TOBN(0xe87673a2, 0xa37173ea), TOBN(0x23848008, 0x53778b65),
+ TOBN(0x10f8441e, 0x05bab43e), TOBN(0xfa11fe12, 0x4621efbe)}},
+ {{TOBN(0x047b772e, 0x81685d7b), TOBN(0x23f27d81, 0xbf34a976),
+ TOBN(0xc27608e2, 0x915f48ef), TOBN(0x3b0b43fa, 0xa521d5c3)},
+ {TOBN(0x7613fb26, 0x63ca7284), TOBN(0x7f5729b4, 0x1d4db837),
+ TOBN(0x87b14898, 0x583b526b), TOBN(0x00b732a6, 0xbbadd3d1)}},
+ {{TOBN(0x8e02f426, 0x2048e396), TOBN(0x436b50b6, 0x383d9de4),
+ TOBN(0xf78d3481, 0x471e85ad), TOBN(0x8b01ea6a, 0xd005c8d6)},
+ {TOBN(0xd3c7afee, 0x97015c07), TOBN(0x46cdf1a9, 0x4e3ba2ae),
+ TOBN(0x7a42e501, 0x83d3a1d2), TOBN(0xd54b5268, 0xb541dff4)}},
+ {{TOBN(0x3f24cf30, 0x4e23e9bc), TOBN(0x4387f816, 0x126e3624),
+ TOBN(0x26a46a03, 0x3b0b6d61), TOBN(0xaf1bc845, 0x8b2d777c)},
+ {TOBN(0x25c401ba, 0x527de79c), TOBN(0x0e1346d4, 0x4261bbb6),
+ TOBN(0x4b96c44b, 0x287b4bc7), TOBN(0x658493c7, 0x5254562f)}},
+ {{TOBN(0x23f949fe, 0xb8a24a20), TOBN(0x17ebfed1, 0xf52ca53f),
+ TOBN(0x9b691bbe, 0xbcfb4853), TOBN(0x5617ff6b, 0x6278a05d)},
+ {TOBN(0x241b34c5, 0xe3c99ebd), TOBN(0xfc64242e, 0x1784156a),
+ TOBN(0x4206482f, 0x695d67df), TOBN(0xb967ce0e, 0xee27c011)}},
+ {{TOBN(0x65db3751, 0x21c80b5d), TOBN(0x2e7a563c, 0xa31ecca0),
+ TOBN(0xe56ffc4e, 0x5238a07e), TOBN(0x3d6c2966, 0x32ced854)},
+ {TOBN(0xe99d7d1a, 0xaf70b885), TOBN(0xafc3bad9, 0x2d686459),
+ TOBN(0x9c78bf46, 0x0cc8ba5b), TOBN(0x5a439519, 0x18955aa3)}},
+ {{TOBN(0xf8b517a8, 0x5fe4e314), TOBN(0xe60234d0, 0xfcb8906f),
+ TOBN(0xffe542ac, 0xf2061b23), TOBN(0x287e191f, 0x6b4cb59c)},
+ {TOBN(0x21857ddc, 0x09d877d8), TOBN(0x1c23478c, 0x14678941),
+ TOBN(0xbbf0c056, 0xb6e05ea4), TOBN(0x82da4b53, 0xb01594fe)}},
+ {{TOBN(0xf7526791, 0xfadb8608), TOBN(0x049e832d, 0x7b74cdf6),
+ TOBN(0xa43581cc, 0xc2b90a34), TOBN(0x73639eb8, 0x9360b10c)},
+ {TOBN(0x4fba331f, 0xe1e4a71b), TOBN(0x6ffd6b93, 0x8072f919),
+ TOBN(0x6e53271c, 0x65679032), TOBN(0x67206444, 0xf14272ce)}},
+ {{TOBN(0xc0f734a3, 0xb2335834), TOBN(0x9526205a, 0x90ef6860),
+ TOBN(0xcb8be717, 0x04e2bb0d), TOBN(0x2418871e, 0x02f383fa)},
+ {TOBN(0xd7177681, 0x4082c157), TOBN(0xcc914ad0, 0x29c20073),
+ TOBN(0xf186c1eb, 0xe587e728), TOBN(0x6fdb3c22, 0x61bcd5fd)}},
+ {{TOBN(0x30d014a6, 0xf2f9f8e9), TOBN(0x963ece23, 0x4fec49d2),
+ TOBN(0x862025c5, 0x9605a8d9), TOBN(0x39874445, 0x19f8929a)},
+ {TOBN(0x01b6ff65, 0x12bf476a), TOBN(0x598a64d8, 0x09cf7d91),
+ TOBN(0xd7ec7749, 0x93be56ca), TOBN(0x10899785, 0xcbb33615)}},
+ {{TOBN(0xb8a092fd, 0x02eee3ad), TOBN(0xa86b3d35, 0x30145270),
+ TOBN(0x323d98c6, 0x8512b675), TOBN(0x4b8bc785, 0x62ebb40f)},
+ {TOBN(0x7d301f54, 0x413f9cde), TOBN(0xa5e4fb4f, 0x2bab5664),
+ TOBN(0x1d2b252d, 0x1cbfec23), TOBN(0xfcd576bb, 0xe177120d)}},
+ {{TOBN(0x04427d3e, 0x83731a34), TOBN(0x2bb9028e, 0xed836e8e),
+ TOBN(0xb36acff8, 0xb612ca7c), TOBN(0xb88fe5ef, 0xd3d9c73a)},
+ {TOBN(0xbe2a6bc6, 0xedea4eb3), TOBN(0x43b93133, 0x488eec77),
+ TOBN(0xf41ff566, 0xb17106e1), TOBN(0x469e9172, 0x654efa32)}},
+ {{TOBN(0xb4480f04, 0x41c23fa3), TOBN(0xb4712eb0, 0xc1989a2e),
+ TOBN(0x3ccbba0f, 0x93a29ca7), TOBN(0x6e205c14, 0xd619428c)},
+ {TOBN(0x90db7957, 0xb3641686), TOBN(0x0432691d, 0x45ac8b4e),
+ TOBN(0x07a759ac, 0xf64e0350), TOBN(0x0514d89c, 0x9c972517)}},
+ {{TOBN(0x1701147f, 0xa8e67fc3), TOBN(0x9e2e0b8b, 0xab2085be),
+ TOBN(0xd5651824, 0xac284e57), TOBN(0x890d4325, 0x74893664)},
+ {TOBN(0x8a7c5e6e, 0xc55e68a3), TOBN(0xbf12e90b, 0x4339c85a),
+ TOBN(0x31846b85, 0xf922b655), TOBN(0x9a54ce4d, 0x0bf4d700)}},
+ {{TOBN(0xd7f4e83a, 0xf1a14295), TOBN(0x916f955c, 0xb285d4f9),
+ TOBN(0xe57bb0e0, 0x99ffdaba), TOBN(0x28a43034, 0xeab0d152)},
+ {TOBN(0x0a36ffa2, 0xb8a9cef8), TOBN(0x5517407e, 0xb9ec051a),
+ TOBN(0x9c796096, 0xea68e672), TOBN(0x853db5fb, 0xfb3c77fb)}},
+ {{TOBN(0x21474ba9, 0xe864a51a), TOBN(0x6c267699, 0x6e8a1b8b),
+ TOBN(0x7c823626, 0x94120a28), TOBN(0xe61e9a48, 0x8383a5db)},
+ {TOBN(0x7dd75003, 0x9f84216d), TOBN(0xab020d07, 0xad43cd85),
+ TOBN(0x9437ae48, 0xda12c659), TOBN(0x6449c2eb, 0xe65452ad)}},
+ {{TOBN(0xcc7c4c1c, 0x2cf9d7c1), TOBN(0x1320886a, 0xee95e5ab),
+ TOBN(0xbb7b9056, 0xbeae170c), TOBN(0xc8a5b250, 0xdbc0d662)},
+ {TOBN(0x4ed81432, 0xc11d2303), TOBN(0x7da66912, 0x1f03769f),
+ TOBN(0x3ac7a5fd, 0x84539828), TOBN(0x14dada94, 0x3bccdd02)}},
+ {{TOBN(0x8b84c321, 0x7ef6b0d1), TOBN(0x52a9477a, 0x7c933f22),
+ TOBN(0x5ef6728a, 0xfd440b82), TOBN(0x5c3bd859, 0x6ce4bd5e)},
+ {TOBN(0x918b80f5, 0xf22c2d3e), TOBN(0x368d5040, 0xb7bb6cc5),
+ TOBN(0xb66142a1, 0x2695a11c), TOBN(0x60ac583a, 0xeb19ea70)}},
+ {{TOBN(0x317cbb98, 0x0eab2437), TOBN(0x8cc08c55, 0x5e2654c8),
+ TOBN(0xfe2d6520, 0xe6d8307f), TOBN(0xe9f147f3, 0x57428993)},
+ {TOBN(0x5f9c7d14, 0xd2fd6cf1), TOBN(0xa3ecd064, 0x2d4fcbb0),
+ TOBN(0xad83fef0, 0x8e7341f7), TOBN(0x643f23a0, 0x3a63115c)}},
+ {{TOBN(0xd38a78ab, 0xe65ab743), TOBN(0xbf7c75b1, 0x35edc89c),
+ TOBN(0x3dd8752e, 0x530df568), TOBN(0xf85c4a76, 0xe308c682)},
+ {TOBN(0x4c9955b2, 0xe68acf37), TOBN(0xa544df3d, 0xab32af85),
+ TOBN(0x4b8ec3f5, 0xa25cf493), TOBN(0x4d8f2764, 0x1a622feb)}},
+ {{TOBN(0x7bb4f7aa, 0xf0dcbc49), TOBN(0x7de551f9, 0x70bbb45b),
+ TOBN(0xcfd0f3e4, 0x9f2ca2e5), TOBN(0xece58709, 0x1f5c76ef)},
+ {TOBN(0x32920edd, 0x167d79ae), TOBN(0x039df8a2, 0xfa7d7ec1),
+ TOBN(0xf46206c0, 0xbb30af91), TOBN(0x1ff5e2f5, 0x22676b59)}},
+ {{TOBN(0x11f4a039, 0x6ea51d66), TOBN(0x506c1445, 0x807d7a26),
+ TOBN(0x60da5705, 0x755a9b24), TOBN(0x8fc8cc32, 0x1f1a319e)},
+ {TOBN(0x83642d4d, 0x9433d67d), TOBN(0x7fa5cb8f, 0x6a7dd296),
+ TOBN(0x576591db, 0x9b7bde07), TOBN(0x13173d25, 0x419716fb)}},
+ {{TOBN(0xea30599d, 0xd5b340ff), TOBN(0xfc6b5297, 0xb0fe76c5),
+ TOBN(0x1c6968c8, 0xab8f5adc), TOBN(0xf723c7f5, 0x901c928d)},
+ {TOBN(0x4203c321, 0x9773d402), TOBN(0xdf7c6aa3, 0x1b51dd47),
+ TOBN(0x3d49e37a, 0x552be23c), TOBN(0x57febee8, 0x0b5a6e87)}},
+ {{TOBN(0xc5ecbee4, 0x7bd8e739), TOBN(0x79d44994, 0xae63bf75),
+ TOBN(0x168bd00f, 0x38fb8923), TOBN(0x75d48ee4, 0xd0533130)},
+ {TOBN(0x554f77aa, 0xdb5cdf33), TOBN(0x3396e896, 0x3c696769),
+ TOBN(0x2fdddbf2, 0xd3fd674e), TOBN(0xbbb8f6ee, 0x99d0e3e5)}},
+ {{TOBN(0x51b90651, 0xcbae2f70), TOBN(0xefc4bc05, 0x93aaa8eb),
+ TOBN(0x8ecd8689, 0xdd1df499), TOBN(0x1aee99a8, 0x22f367a5)},
+ {TOBN(0x95d485b9, 0xae8274c5), TOBN(0x6c14d445, 0x7d30b39c),
+ TOBN(0xbafea90b, 0xbcc1ef81), TOBN(0x7c5f317a, 0xa459a2ed)}},
+ {{TOBN(0x01211075, 0x4ef44227), TOBN(0xa17bed6e, 0xdc20f496),
+ TOBN(0x0cdfe424, 0x819853cd), TOBN(0x13793298, 0xf71e2ce7)},
+ {TOBN(0x3c1f3078, 0xdbbe307b), TOBN(0x6dd1c20e, 0x76ee9936),
+ TOBN(0x23ee4b57, 0x423caa20), TOBN(0x4ac3793b, 0x8efb840e)}},
+ {{TOBN(0x934438eb, 0xed1f8ca0), TOBN(0x3e546658, 0x4ebb25a2),
+ TOBN(0xc415af0e, 0xc069896f), TOBN(0xc13eddb0, 0x9a5aa43d)},
+ {TOBN(0x7a04204f, 0xd49eb8f6), TOBN(0xd0d5bdfc, 0xd74f1670),
+ TOBN(0x3697e286, 0x56fc0558), TOBN(0x10207371, 0x01cebade)}},
+ {{TOBN(0x5f87e690, 0x0647a82b), TOBN(0x908e0ed4, 0x8f40054f),
+ TOBN(0xa9f633d4, 0x79853803), TOBN(0x8ed13c9a, 0x4a28b252)},
+ {TOBN(0x3e2ef676, 0x1f460f64), TOBN(0x53930b9b, 0x36d06336),
+ TOBN(0x347073ac, 0x8fc4979b), TOBN(0x84380e0e, 0x5ecd5597)}},
+ {{TOBN(0xe3b22c6b, 0xc4fe3c39), TOBN(0xba4a8153, 0x6c7bebdf),
+ TOBN(0xf23ab6b7, 0x25693459), TOBN(0x53bc3770, 0x14922b11)},
+ {TOBN(0x4645c8ab, 0x5afc60db), TOBN(0xaa022355, 0x20b9f2a3),
+ TOBN(0x52a2954c, 0xce0fc507), TOBN(0x8c2731bb, 0x7ce1c2e7)}},
+ {{TOBN(0xf39608ab, 0x18a0339d), TOBN(0xac7a658d, 0x3735436c),
+ TOBN(0xb22c2b07, 0xcd992b4f), TOBN(0x4e83daec, 0xf40dcfd4)},
+ {TOBN(0x8a34c7be, 0x2f39ea3e), TOBN(0xef0c005f, 0xb0a56d2e),
+ TOBN(0x62731f6a, 0x6edd8038), TOBN(0x5721d740, 0x4e3cb075)}},
+ {{TOBN(0x1ea41511, 0xfbeeee1b), TOBN(0xd1ef5e73, 0xef1d0c05),
+ TOBN(0x42feefd1, 0x73c07d35), TOBN(0xe530a00a, 0x8a329493)},
+ {TOBN(0x5d55b7fe, 0xf15ebfb0), TOBN(0x549de03c, 0xd322491a),
+ TOBN(0xf7b5f602, 0x745b3237), TOBN(0x3632a3a2, 0x1ab6e2b6)}},
+ {{TOBN(0x0d3bba89, 0x0ef59f78), TOBN(0x0dfc6443, 0xc9e52b9a),
+ TOBN(0x1dc79699, 0x72631447), TOBN(0xef033917, 0xb3be20b1)},
+ {TOBN(0x0c92735d, 0xb1383948), TOBN(0xc1fc29a2, 0xc0dd7d7d),
+ TOBN(0x6485b697, 0x403ed068), TOBN(0x13bfaab3, 0xaac93bdc)}},
+ {{TOBN(0x410dc6a9, 0x0deeaf52), TOBN(0xb003fb02, 0x4c641c15),
+ TOBN(0x1384978c, 0x5bc504c4), TOBN(0x37640487, 0x864a6a77)},
+ {TOBN(0x05991bc6, 0x222a77da), TOBN(0x62260a57, 0x5e47eb11),
+ TOBN(0xc7af6613, 0xf21b432c), TOBN(0x22f3acc9, 0xab4953e9)}},
+ {{TOBN(0x52934922, 0x8e41d155), TOBN(0x4d024568, 0x3ac059ef),
+ TOBN(0xb0201755, 0x4d884411), TOBN(0xce8055cf, 0xa59a178f)},
+ {TOBN(0xcd77d1af, 0xf6204549), TOBN(0xa0a00a3e, 0xc7066759),
+ TOBN(0x471071ef, 0x0272c229), TOBN(0x009bcf6b, 0xd3c4b6b0)}},
+ {{TOBN(0x2a2638a8, 0x22305177), TOBN(0xd51d59df, 0x41645bbf),
+ TOBN(0xa81142fd, 0xc0a7a3c0), TOBN(0xa17eca6d, 0x4c7063ee)},
+ {TOBN(0x0bb887ed, 0x60d9dcec), TOBN(0xd6d28e51, 0x20ad2455),
+ TOBN(0xebed6308, 0xa67102ba), TOBN(0x042c3114, 0x8bffa408)}},
+ {{TOBN(0xfd099ac5, 0x8aa68e30), TOBN(0x7a6a3d7c, 0x1483513e),
+ TOBN(0xffcc6b75, 0xba2d8f0c), TOBN(0x54dacf96, 0x1e78b954)},
+ {TOBN(0xf645696f, 0xa4a9af89), TOBN(0x3a411940, 0x06ac98ec),
+ TOBN(0x41b8b3f6, 0x22a67a20), TOBN(0x2d0b1e0f, 0x99dec626)}},
+ {{TOBN(0x27c89192, 0x40be34e8), TOBN(0xc7162b37, 0x91907f35),
+ TOBN(0x90188ec1, 0xa956702b), TOBN(0xca132f7d, 0xdf93769c)},
+ {TOBN(0x3ece44f9, 0x0e2025b4), TOBN(0x67aaec69, 0x0c62f14c),
+ TOBN(0xad741418, 0x22e3cc11), TOBN(0xcf9b75c3, 0x7ff9a50e)}},
+ {{TOBN(0x02fa2b16, 0x4d348272), TOBN(0xbd99d61a, 0x9959d56d),
+ TOBN(0xbc4f19db, 0x18762916), TOBN(0xcc7cce50, 0x49c1ac80)},
+ {TOBN(0x4d59ebaa, 0xd846bd83), TOBN(0x8775a9dc, 0xa9202849),
+ TOBN(0x07ec4ae1, 0x6e1f4ca9), TOBN(0x27eb5875, 0xba893f11)}},
+ {{TOBN(0x00284d51, 0x662cc565), TOBN(0x82353a6b, 0x0db4138d),
+ TOBN(0xd9c7aaaa, 0xaa32a594), TOBN(0xf5528b5e, 0xa5669c47)},
+ {TOBN(0xf3220231, 0x2f23c5ff), TOBN(0xe3e8147a, 0x6affa3a1),
+ TOBN(0xfb423d5c, 0x202ddda0), TOBN(0x3d6414ac, 0x6b871bd4)}},
+ {{TOBN(0x586f82e1, 0xa51a168a), TOBN(0xb712c671, 0x48ae5448),
+ TOBN(0x9a2e4bd1, 0x76233eb8), TOBN(0x0188223a, 0x78811ca9)},
+ {TOBN(0x553c5e21, 0xf7c18de1), TOBN(0x7682e451, 0xb27bb286),
+ TOBN(0x3ed036b3, 0x0e51e929), TOBN(0xf487211b, 0xec9cb34f)}},
+ {{TOBN(0x0d094277, 0x0c24efc8), TOBN(0x0349fd04, 0xbef737a4),
+ TOBN(0x6d1c9dd2, 0x514cdd28), TOBN(0x29c135ff, 0x30da9521)},
+ {TOBN(0xea6e4508, 0xf78b0b6f), TOBN(0x176f5dd2, 0x678c143c),
+ TOBN(0x08148418, 0x4be21e65), TOBN(0x27f7525c, 0xe7df38c4)}},
+ {{TOBN(0x1fb70e09, 0x748ab1a4), TOBN(0x9cba50a0, 0x5efe4433),
+ TOBN(0x7846c7a6, 0x15f75af2), TOBN(0x2a7c2c57, 0x5ee73ea8)},
+ {TOBN(0x42e566a4, 0x3f0a449a), TOBN(0x45474c3b, 0xad90fc3d),
+ TOBN(0x7447be3d, 0x8b61d057), TOBN(0x3e9d1cf1, 0x3a4ec092)}},
+ {{TOBN(0x1603e453, 0xf380a6e6), TOBN(0x0b86e431, 0x9b1437c2),
+ TOBN(0x7a4173f2, 0xef29610a), TOBN(0x8fa729a7, 0xf03d57f7)},
+ {TOBN(0x3e186f6e, 0x6c9c217e), TOBN(0xbe1d3079, 0x91919524),
+ TOBN(0x92a62a70, 0x153d4fb1), TOBN(0x32ed3e34, 0xd68c2f71)}},
+ {{TOBN(0xd785027f, 0x9eb1a8b7), TOBN(0xbc37eb77, 0xc5b22fe8),
+ TOBN(0x466b34f0, 0xb9d6a191), TOBN(0x008a89af, 0x9a05f816)},
+ {TOBN(0x19b028fb, 0x7d42c10a), TOBN(0x7fe8c92f, 0x49b3f6b8),
+ TOBN(0x58907cc0, 0xa5a0ade3), TOBN(0xb3154f51, 0x559d1a7c)}},
+ {{TOBN(0x5066efb6, 0xd9790ed6), TOBN(0xa77a0cbc, 0xa6aa793b),
+ TOBN(0x1a915f3c, 0x223e042e), TOBN(0x1c5def04, 0x69c5874b)},
+ {TOBN(0x0e830078, 0x73b6c1da), TOBN(0x55cf85d2, 0xfcd8557a),
+ TOBN(0x0f7c7c76, 0x0460f3b1), TOBN(0x87052acb, 0x46e58063)}},
+ {{TOBN(0x09212b80, 0x907eae66), TOBN(0x3cb068e0, 0x4d721c89),
+ TOBN(0xa87941ae, 0xdd45ac1c), TOBN(0xde8d5c0d, 0x0daa0dbb)},
+ {TOBN(0xda421fdc, 0xe3502e6e), TOBN(0xc8944201, 0x4d89a084),
+ TOBN(0x7307ba5e, 0xf0c24bfb), TOBN(0xda212beb, 0x20bde0ef)}},
+ {{TOBN(0xea2da24b, 0xf82ce682), TOBN(0x058d3816, 0x07f71fe4),
+ TOBN(0x35a02462, 0x5ffad8de), TOBN(0xcd7b05dc, 0xaadcefab)},
+ {TOBN(0xd442f8ed, 0x1d9f54ec), TOBN(0x8be3d618, 0xb2d3b5ca),
+ TOBN(0xe2220ed0, 0xe06b2ce2), TOBN(0x82699a5f, 0x1b0da4c0)}},
+ {{TOBN(0x3ff106f5, 0x71c0c3a7), TOBN(0x8f580f5a, 0x0d34180c),
+ TOBN(0x4ebb120e, 0x22d7d375), TOBN(0x5e5782cc, 0xe9513675)},
+ {TOBN(0x2275580c, 0x99c82a70), TOBN(0xe8359fbf, 0x15ea8c4c),
+ TOBN(0x53b48db8, 0x7b415e70), TOBN(0xaacf2240, 0x100c6014)}},
+ {{TOBN(0x9faaccf5, 0xe4652f1d), TOBN(0xbd6fdd2a, 0xd56157b2),
+ TOBN(0xa4f4fb1f, 0x6261ec50), TOBN(0x244e55ad, 0x476bcd52)},
+ {TOBN(0x881c9305, 0x047d320b), TOBN(0x1ca983d5, 0x6181263f),
+ TOBN(0x354e9a44, 0x278fb8ee), TOBN(0xad2dbc0f, 0x396e4964)}},
+ {{TOBN(0x723f3aa2, 0x9268b3de), TOBN(0x0d1ca29a, 0xe6e0609a),
+ TOBN(0x794866aa, 0x6cf44252), TOBN(0x0b59f3e3, 0x01af87ed)},
+ {TOBN(0xe234e5ff, 0x7f4a6c51), TOBN(0xa8768fd2, 0x61dc2f7e),
+ TOBN(0xdafc7332, 0x0a94d81f), TOBN(0xd7f84282, 0x06938ce1)}},
+ {{TOBN(0xae0b3c0e, 0x0546063e), TOBN(0x7fbadcb2, 0x5d61abc6),
+ TOBN(0xd5d7a2c9, 0x369ac400), TOBN(0xa5978d09, 0xae67d10c)},
+ {TOBN(0x290f211e, 0x4f85eaac), TOBN(0xe61e2ad1, 0xfacac681),
+ TOBN(0xae125225, 0x388384cd), TOBN(0xa7fb68e9, 0xccfde30f)}},
+ {{TOBN(0x7a59b936, 0x3daed4c2), TOBN(0x80a9aa40, 0x2606f789),
+ TOBN(0xb40c1ea5, 0xf6a6d90a), TOBN(0x948364d3, 0x514d5885)},
+ {TOBN(0x062ebc60, 0x70985182), TOBN(0xa6db5b0e, 0x33310895),
+ TOBN(0x64a12175, 0xe329c2f5), TOBN(0xc5f25bd2, 0x90ea237e)}},
+ {{TOBN(0x7915c524, 0x2d0a4c23), TOBN(0xeb5d26e4, 0x6bb3cc52),
+ TOBN(0x369a9116, 0xc09e2c92), TOBN(0x0c527f92, 0xcf182cf8)},
+ {TOBN(0x9e591938, 0x2aede0ac), TOBN(0xb2922208, 0x6cc34939),
+ TOBN(0x3c9d8962, 0x99a34361), TOBN(0x3c81836d, 0xc1905fe6)}},
+ {{TOBN(0x4bfeb57f, 0xa001ec5a), TOBN(0xe993f5bb, 0xa0dc5dba),
+ TOBN(0x47884109, 0x724a1380), TOBN(0x8a0369ab, 0x32fe9a04)},
+ {TOBN(0xea068d60, 0x8c927db8), TOBN(0xbf5f37cf, 0x94655741),
+ TOBN(0x47d402a2, 0x04b6c7ea), TOBN(0x4551c295, 0x6af259cb)}},
+ {{TOBN(0x698b71e7, 0xed77ee8b), TOBN(0xbddf7bd0, 0xf309d5c7),
+ TOBN(0x6201c22c, 0x34e780ca), TOBN(0xab04f7d8, 0x4c295ef4)},
+ {TOBN(0x1c947294, 0x4313a8ce), TOBN(0xe532e4ac, 0x92ca4cfe),
+ TOBN(0x89738f80, 0xd0a7a97a), TOBN(0xec088c88, 0xa580fd5b)}},
+ {{TOBN(0x612b1ecc, 0x42ce9e51), TOBN(0x8f9840fd, 0xb25fdd2a),
+ TOBN(0x3cda78c0, 0x01e7f839), TOBN(0x546b3d3a, 0xece05480)},
+ {TOBN(0x271719a9, 0x80d30916), TOBN(0x45497107, 0x584c20c4),
+ TOBN(0xaf8f9478, 0x5bc78608), TOBN(0x28c7d484, 0x277e2a4c)}},
+ {{TOBN(0xfce01767, 0x88a2ffe4), TOBN(0xdc506a35, 0x28e169a5),
+ TOBN(0x0ea10861, 0x7af9c93a), TOBN(0x1ed24361, 0x03fa0e08)},
+ {TOBN(0x96eaaa92, 0xa3d694e7), TOBN(0xc0f43b4d, 0xef50bc74),
+ TOBN(0xce6aa58c, 0x64114db4), TOBN(0x8218e8ea, 0x7c000fd4)}},
+ {{TOBN(0xac815dfb, 0x185f8844), TOBN(0xcd7e90cb, 0x1557abfb),
+ TOBN(0x23d16655, 0xafbfecdf), TOBN(0x80f3271f, 0x085cac4a)},
+ {TOBN(0x7fc39aa7, 0xd0e62f47), TOBN(0x88d519d1, 0x460a48e5),
+ TOBN(0x59559ac4, 0xd28f101e), TOBN(0x7981d9e9, 0xca9ae816)}},
+ {{TOBN(0x5c38652c, 0x9ac38203), TOBN(0x86eaf87f, 0x57657fe5),
+ TOBN(0x568fc472, 0xe21f5416), TOBN(0x2afff39c, 0xe7e597b5)},
+ {TOBN(0x3adbbb07, 0x256d4eab), TOBN(0x22598692, 0x8285ab89),
+ TOBN(0x35f8112a, 0x041caefe), TOBN(0x95df02e3, 0xa5064c8b)}},
+ {{TOBN(0x4d63356e, 0xc7004bf3), TOBN(0x230a08f4, 0xdb83c7de),
+ TOBN(0xca27b270, 0x8709a7b7), TOBN(0x0d1c4cc4, 0xcb9abd2d)},
+ {TOBN(0x8a0bc66e, 0x7550fee8), TOBN(0x369cd4c7, 0x9cf7247e),
+ TOBN(0x75562e84, 0x92b5b7e7), TOBN(0x8fed0da0, 0x5802af7b)}},
+ {{TOBN(0x6a7091c2, 0xe48fb889), TOBN(0x26882c13, 0x7b8a9d06),
+ TOBN(0xa2498663, 0x1b82a0e2), TOBN(0x844ed736, 0x3518152d)},
+ {TOBN(0x282f476f, 0xd86e27c7), TOBN(0xa04edaca, 0x04afefdc),
+ TOBN(0x8b256ebc, 0x6119e34d), TOBN(0x56a413e9, 0x0787d78b)}}},
+ {{{TOBN(0x82ee061d, 0x5a74be50), TOBN(0xe41781c4, 0xdea16ff5),
+ TOBN(0xe0b0c81e, 0x99bfc8a2), TOBN(0x624f4d69, 0x0b547e2d)},
+ {TOBN(0x3a83545d, 0xbdcc9ae4), TOBN(0x2573dbb6, 0x409b1e8e),
+ TOBN(0x482960c4, 0xa6c93539), TOBN(0xf01059ad, 0x5ae18798)}},
+ {{TOBN(0x715c9f97, 0x3112795f), TOBN(0xe8244437, 0x984e6ee1),
+ TOBN(0x55cb4858, 0xecb66bcd), TOBN(0x7c136735, 0xabaffbee)},
+ {TOBN(0x54661595, 0x5dbec38e), TOBN(0x51c0782c, 0x388ad153),
+ TOBN(0x9ba4c53a, 0xc6e0952f), TOBN(0x27e6782a, 0x1b21dfa8)}},
+ {{TOBN(0x682f903d, 0x4ed2dbc2), TOBN(0x0eba59c8, 0x7c3b2d83),
+ TOBN(0x8e9dc84d, 0x9c7e9335), TOBN(0x5f9b21b0, 0x0eb226d7)},
+ {TOBN(0xe33bd394, 0xaf267bae), TOBN(0xaa86cc25, 0xbe2e15ae),
+ TOBN(0x4f0bf67d, 0x6a8ec500), TOBN(0x5846aa44, 0xf9630658)}},
+ {{TOBN(0xfeb09740, 0xe2c2bf15), TOBN(0x627a2205, 0xa9e99704),
+ TOBN(0xec8d73d0, 0xc2fbc565), TOBN(0x223eed8f, 0xc20c8de8)},
+ {TOBN(0x1ee32583, 0xa8363b49), TOBN(0x1a0b6cb9, 0xc9c2b0a6),
+ TOBN(0x49f7c3d2, 0x90dbc85c), TOBN(0xa8dfbb97, 0x1ef4c1ac)}},
+ {{TOBN(0xafb34d4c, 0x65c7c2ab), TOBN(0x1d4610e7, 0xe2c5ea84),
+ TOBN(0x893f6d1b, 0x973c4ab5), TOBN(0xa3cdd7e9, 0x945ba5c4)},
+ {TOBN(0x60514983, 0x064417ee), TOBN(0x1459b23c, 0xad6bdf2b),
+ TOBN(0x23b2c341, 0x5cf726c3), TOBN(0x3a829635, 0x32d6354a)}},
+ {{TOBN(0x294f901f, 0xab192c18), TOBN(0xec5fcbfe, 0x7030164f),
+ TOBN(0xe2e2fcb7, 0xe2246ba6), TOBN(0x1e7c88b3, 0x221a1a0c)},
+ {TOBN(0x72c7dd93, 0xc92d88c5), TOBN(0x41c2148e, 0x1106fb59),
+ TOBN(0x547dd4f5, 0xa0f60f14), TOBN(0xed9b52b2, 0x63960f31)}},
+ {{TOBN(0x6c8349eb, 0xb0a5b358), TOBN(0xb154c5c2, 0x9e7e2ed6),
+ TOBN(0xcad5eccf, 0xeda462db), TOBN(0xf2d6dbe4, 0x2de66b69)},
+ {TOBN(0x426aedf3, 0x8665e5b2), TOBN(0x488a8513, 0x7b7f5723),
+ TOBN(0x15cc43b3, 0x8bcbb386), TOBN(0x27ad0af3, 0xd791d879)}},
+ {{TOBN(0xc16c236e, 0x846e364f), TOBN(0x7f33527c, 0xdea50ca0),
+ TOBN(0xc4810775, 0x0926b86d), TOBN(0x6c2a3609, 0x0598e70c)},
+ {TOBN(0xa6755e52, 0xf024e924), TOBN(0xe0fa07a4, 0x9db4afca),
+ TOBN(0x15c3ce7d, 0x66831790), TOBN(0x5b4ef350, 0xa6cbb0d6)}},
+ {{TOBN(0x2c4aafc4, 0xb6205969), TOBN(0x42563f02, 0xf6c7854f),
+ TOBN(0x016aced5, 0x1d983b48), TOBN(0xfeb356d8, 0x99949755)},
+ {TOBN(0x8c2a2c81, 0xd1a39bd7), TOBN(0x8f44340f, 0xe6934ae9),
+ TOBN(0x148cf91c, 0x447904da), TOBN(0x7340185f, 0x0f51a926)}},
+ {{TOBN(0x2f8f00fb, 0x7409ab46), TOBN(0x057e78e6, 0x80e289b2),
+ TOBN(0x03e5022c, 0xa888e5d1), TOBN(0x3c87111a, 0x9dede4e2)},
+ {TOBN(0x5b9b0e1c, 0x7809460b), TOBN(0xe751c852, 0x71c9abc7),
+ TOBN(0x8b944e28, 0xc7cc1dc9), TOBN(0x4f201ffa, 0x1d3cfa08)}},
+ {{TOBN(0x02fc905c, 0x3e6721ce), TOBN(0xd52d70da, 0xd0b3674c),
+ TOBN(0x5dc2e5ca, 0x18810da4), TOBN(0xa984b273, 0x5c69dd99)},
+ {TOBN(0x63b92527, 0x84de5ca4), TOBN(0x2f1c9872, 0xc852dec4),
+ TOBN(0x18b03593, 0xc2e3de09), TOBN(0x19d70b01, 0x9813dc2f)}},
+ {{TOBN(0x42806b2d, 0xa6dc1d29), TOBN(0xd3030009, 0xf871e144),
+ TOBN(0xa1feb333, 0xaaf49276), TOBN(0xb5583b9e, 0xc70bc04b)},
+ {TOBN(0x1db0be78, 0x95695f20), TOBN(0xfc841811, 0x89d012b5),
+ TOBN(0x6409f272, 0x05f61643), TOBN(0x40d34174, 0xd5883128)}},
+ {{TOBN(0xd79196f5, 0x67419833), TOBN(0x6059e252, 0x863b7b08),
+ TOBN(0x84da1817, 0x1c56700c), TOBN(0x5758ee56, 0xb28d3ec4)},
+ {TOBN(0x7da2771d, 0x013b0ea6), TOBN(0xfddf524b, 0x54c5e9b9),
+ TOBN(0x7df4faf8, 0x24305d80), TOBN(0x58f5c1bf, 0x3a97763f)}},
+ {{TOBN(0xa5af37f1, 0x7c696042), TOBN(0xd4cba22c, 0x4a2538de),
+ TOBN(0x211cb995, 0x9ea42600), TOBN(0xcd105f41, 0x7b069889)},
+ {TOBN(0xb1e1cf19, 0xddb81e74), TOBN(0x472f2d89, 0x5157b8ca),
+ TOBN(0x086fb008, 0xee9db885), TOBN(0x365cd570, 0x0f26d131)}},
+ {{TOBN(0x284b02bb, 0xa2be7053), TOBN(0xdcbbf7c6, 0x7ab9a6d6),
+ TOBN(0x4425559c, 0x20f7a530), TOBN(0x961f2dfa, 0x188767c8)},
+ {TOBN(0xe2fd9435, 0x70dc80c4), TOBN(0x104d6b63, 0xf0784120),
+ TOBN(0x7f592bc1, 0x53567122), TOBN(0xf6bc1246, 0xf688ad77)}},
+ {{TOBN(0x05214c05, 0x0f15dde9), TOBN(0xa47a76a8, 0x0d5f2b82),
+ TOBN(0xbb254d30, 0x62e82b62), TOBN(0x11a05fe0, 0x3ec955ee)},
+ {TOBN(0x7eaff46e, 0x9d529b36), TOBN(0x55ab1301, 0x8f9e3df6),
+ TOBN(0xc463e371, 0x99317698), TOBN(0xfd251438, 0xccda47ad)}},
+ {{TOBN(0xca9c3547, 0x23d695ea), TOBN(0x48ce626e, 0x16e589b5),
+ TOBN(0x6b5b64c7, 0xb187d086), TOBN(0xd02e1794, 0xb2207948)},
+ {TOBN(0x8b58e98f, 0x7198111d), TOBN(0x90ca6305, 0xdcf9c3cc),
+ TOBN(0x5691fe72, 0xf34089b0), TOBN(0x60941af1, 0xfc7c80ff)}},
+ {{TOBN(0xa09bc0a2, 0x22eb51e5), TOBN(0xc0bb7244, 0xaa9cf09a),
+ TOBN(0x36a8077f, 0x80159f06), TOBN(0x8b5c989e, 0xdddc560e)},
+ {TOBN(0x19d2f316, 0x512e1f43), TOBN(0x02eac554, 0xad08ff62),
+ TOBN(0x012ab84c, 0x07d20b4e), TOBN(0x37d1e115, 0xd6d4e4e1)}},
+ {{TOBN(0xb6443e1a, 0xab7b19a8), TOBN(0xf08d067e, 0xdef8cd45),
+ TOBN(0x63adf3e9, 0x685e03da), TOBN(0xcf15a10e, 0x4792b916)},
+ {TOBN(0xf44bcce5, 0xb738a425), TOBN(0xebe131d5, 0x9636b2fd),
+ TOBN(0x94068841, 0x7850d605), TOBN(0x09684eaa, 0xb40d749d)}},
+ {{TOBN(0x8c3c669c, 0x72ba075b), TOBN(0x89f78b55, 0xba469015),
+ TOBN(0x5706aade, 0x3e9f8ba8), TOBN(0x6d8bd565, 0xb32d7ed7)},
+ {TOBN(0x25f4e63b, 0x805f08d6), TOBN(0x7f48200d, 0xc3bcc1b5),
+ TOBN(0x4e801968, 0xb025d847), TOBN(0x74afac04, 0x87cbe0a8)}},
+ {{TOBN(0x43ed2c2b, 0x7e63d690), TOBN(0xefb6bbf0, 0x0223cdb8),
+ TOBN(0x4fec3cae, 0x2884d3fe), TOBN(0x065ecce6, 0xd75e25a4)},
+ {TOBN(0x6c2294ce, 0x69f79071), TOBN(0x0d9a8e5f, 0x044b8666),
+ TOBN(0x5009f238, 0x17b69d8f), TOBN(0x3c29f8fe, 0xc5dfdaf7)}},
+ {{TOBN(0x9067528f, 0xebae68c4), TOBN(0x5b385632, 0x30c5ba21),
+ TOBN(0x540df119, 0x1fdd1aec), TOBN(0xcf37825b, 0xcfba4c78)},
+ {TOBN(0x77eff980, 0xbeb11454), TOBN(0x40a1a991, 0x60c1b066),
+ TOBN(0xe8018980, 0xf889a1c7), TOBN(0xb9c52ae9, 0x76c24be0)}},
+ {{TOBN(0x05fbbcce, 0x45650ef4), TOBN(0xae000f10, 0x8aa29ac7),
+ TOBN(0x884b7172, 0x4f04c470), TOBN(0x7cd4fde2, 0x19bb5c25)},
+ {TOBN(0x6477b22a, 0xe8840869), TOBN(0xa8868859, 0x5fbd0686),
+ TOBN(0xf23cc02e, 0x1116dfba), TOBN(0x76cd563f, 0xd87d7776)}},
+ {{TOBN(0xe2a37598, 0xa9d82abf), TOBN(0x5f188ccb, 0xe6c170f5),
+ TOBN(0x81682200, 0x5066b087), TOBN(0xda22c212, 0xc7155ada)},
+ {TOBN(0x151e5d3a, 0xfbddb479), TOBN(0x4b606b84, 0x6d715b99),
+ TOBN(0x4a73b54b, 0xf997cb2e), TOBN(0x9a1bfe43, 0x3ecd8b66)}},
+ {{TOBN(0x1c312809, 0x2a67d48a), TOBN(0xcd6a671e, 0x031fa9e2),
+ TOBN(0xbec3312a, 0x0e43a34a), TOBN(0x1d935639, 0x55ef47d3)},
+ {TOBN(0x5ea02489, 0x8fea73ea), TOBN(0x8247b364, 0xa035afb2),
+ TOBN(0xb58300a6, 0x5265b54c), TOBN(0x3286662f, 0x722c7148)}},
+ {{TOBN(0xb77fd76b, 0xb4ec4c20), TOBN(0xf0a12fa7, 0x0f3fe3fd),
+ TOBN(0xf845bbf5, 0x41d8c7e8), TOBN(0xe4d969ca, 0x5ec10aa8)},
+ {TOBN(0x4c0053b7, 0x43e232a3), TOBN(0xdc7a3fac, 0x37f8a45a),
+ TOBN(0x3c4261c5, 0x20d81c8f), TOBN(0xfd4b3453, 0xb00eab00)}},
+ {{TOBN(0x76d48f86, 0xd36e3062), TOBN(0x626c5277, 0xa143ff02),
+ TOBN(0x538174de, 0xaf76f42e), TOBN(0x2267aa86, 0x6407ceac)},
+ {TOBN(0xfad76351, 0x72e572d5), TOBN(0xab861af7, 0xba7330eb),
+ TOBN(0xa0a1c8c7, 0x418d8657), TOBN(0x988821cb, 0x20289a52)}},
+ {{TOBN(0x79732522, 0xcccc18ad), TOBN(0xaadf3f8d, 0xf1a6e027),
+ TOBN(0xf7382c93, 0x17c2354d), TOBN(0x5ce1680c, 0xd818b689)},
+ {TOBN(0x359ebbfc, 0xd9ecbee9), TOBN(0x4330689c, 0x1cae62ac),
+ TOBN(0xb55ce5b4, 0xc51ac38a), TOBN(0x7921dfea, 0xfe238ee8)}},
+ {{TOBN(0x3972bef8, 0x271d1ca5), TOBN(0x3e423bc7, 0xe8aabd18),
+ TOBN(0x57b09f3f, 0x44a3e5e3), TOBN(0x5da886ae, 0x7b444d66)},
+ {TOBN(0x68206634, 0xa9964375), TOBN(0x356a2fa3, 0x699cd0ff),
+ TOBN(0xaf0faa24, 0xdba515e9), TOBN(0x536e1f5c, 0xb321d79a)}},
+ {{TOBN(0xd3b9913a, 0x5c04e4ea), TOBN(0xd549dcfe, 0xd6f11513),
+ TOBN(0xee227bf5, 0x79fd1d94), TOBN(0x9f35afee, 0xb43f2c67)},
+ {TOBN(0xd2638d24, 0xf1314f53), TOBN(0x62baf948, 0xcabcd822),
+ TOBN(0x5542de29, 0x4ef48db0), TOBN(0xb3eb6a04, 0xfc5f6bb2)}},
+ {{TOBN(0x23c110ae, 0x1208e16a), TOBN(0x1a4d15b5, 0xf8363e24),
+ TOBN(0x30716844, 0x164be00b), TOBN(0xa8e24824, 0xf6f4690d)},
+ {TOBN(0x548773a2, 0x90b170cf), TOBN(0xa1bef331, 0x42f191f4),
+ TOBN(0x70f418d0, 0x9247aa97), TOBN(0xea06028e, 0x48be9147)}},
+ {{TOBN(0xe13122f3, 0xdbfb894e), TOBN(0xbe9b79f6, 0xce274b18),
+ TOBN(0x85a49de5, 0xca58aadf), TOBN(0x24957758, 0x11487351)},
+ {TOBN(0x111def61, 0xbb939099), TOBN(0x1d6a974a, 0x26d13694),
+ TOBN(0x4474b4ce, 0xd3fc253b), TOBN(0x3a1485e6, 0x4c5db15e)}},
+ {{TOBN(0xe79667b4, 0x147c15b4), TOBN(0xe34f553b, 0x7bc61301),
+ TOBN(0x032b80f8, 0x17094381), TOBN(0x55d8bafd, 0x723eaa21)},
+ {TOBN(0x5a987995, 0xf1c0e74e), TOBN(0x5a9b292e, 0xebba289c),
+ TOBN(0x413cd4b2, 0xeb4c8251), TOBN(0x98b5d243, 0xd162db0a)}},
+ {{TOBN(0xbb47bf66, 0x68342520), TOBN(0x08d68949, 0xbaa862d1),
+ TOBN(0x11f349c7, 0xe906abcd), TOBN(0x454ce985, 0xed7bf00e)},
+ {TOBN(0xacab5c9e, 0xb55b803b), TOBN(0xb03468ea, 0x31e3c16d),
+ TOBN(0x5c24213d, 0xd273bf12), TOBN(0x211538eb, 0x71587887)}},
+ {{TOBN(0x198e4a2f, 0x731dea2d), TOBN(0xd5856cf2, 0x74ed7b2a),
+ TOBN(0x86a632eb, 0x13a664fe), TOBN(0x932cd909, 0xbda41291)},
+ {TOBN(0x850e95d4, 0xc0c4ddc0), TOBN(0xc0f422f8, 0x347fc2c9),
+ TOBN(0xe68cbec4, 0x86076bcb), TOBN(0xf9e7c0c0, 0xcd6cd286)}},
+ {{TOBN(0x65994ddb, 0x0f5f27ca), TOBN(0xe85461fb, 0xa80d59ff),
+ TOBN(0xff05481a, 0x66601023), TOBN(0xc665427a, 0xfc9ebbfb)},
+ {TOBN(0xb0571a69, 0x7587fd52), TOBN(0x935289f8, 0x8d49efce),
+ TOBN(0x61becc60, 0xea420688), TOBN(0xb22639d9, 0x13a786af)}},
+ {{TOBN(0x1a8e6220, 0x361ecf90), TOBN(0x001f23e0, 0x25506463),
+ TOBN(0xe4ae9b5d, 0x0a5c2b79), TOBN(0xebc9cdad, 0xd8149db5)},
+ {TOBN(0xb33164a1, 0x934aa728), TOBN(0x750eb00e, 0xae9b60f3),
+ TOBN(0x5a91615b, 0x9b9cfbfd), TOBN(0x97015cbf, 0xef45f7f6)}},
+ {{TOBN(0xb462c4a5, 0xbf5151df), TOBN(0x21adcc41, 0xb07118f2),
+ TOBN(0xd60c545b, 0x043fa42c), TOBN(0xfc21aa54, 0xe96be1ab)},
+ {TOBN(0xe84bc32f, 0x4e51ea80), TOBN(0x3dae45f0, 0x259b5d8d),
+ TOBN(0xbb73c7eb, 0xc38f1b5e), TOBN(0xe405a74a, 0xe8ae617d)}},
+ {{TOBN(0xbb1ae9c6, 0x9f1c56bd), TOBN(0x8c176b98, 0x49f196a4),
+ TOBN(0xc448f311, 0x6875092b), TOBN(0xb5afe3de, 0x9f976033)},
+ {TOBN(0xa8dafd49, 0x145813e5), TOBN(0x687fc4d9, 0xe2b34226),
+ TOBN(0xf2dfc92d, 0x4c7ff57f), TOBN(0x004e3fc1, 0x401f1b46)}},
+ {{TOBN(0x5afddab6, 0x1430c9ab), TOBN(0x0bdd41d3, 0x2238e997),
+ TOBN(0xf0947430, 0x418042ae), TOBN(0x71f9adda, 0xcdddc4cb)},
+ {TOBN(0x7090c016, 0xc52dd907), TOBN(0xd9bdf44d, 0x29e2047f),
+ TOBN(0xe6f1fe80, 0x1b1011a6), TOBN(0xb63accbc, 0xd9acdc78)}},
+ {{TOBN(0xcfc7e235, 0x1272a95b), TOBN(0x0c667717, 0xa6276ac8),
+ TOBN(0x3c0d3709, 0xe2d7eef7), TOBN(0x5add2b06, 0x9a685b3e)},
+ {TOBN(0x363ad32d, 0x14ea5d65), TOBN(0xf8e01f06, 0x8d7dd506),
+ TOBN(0xc9ea2213, 0x75b4aac6), TOBN(0xed2a2bf9, 0x0d353466)}},
+ {{TOBN(0x439d79b5, 0xe9d3a7c3), TOBN(0x8e0ee5a6, 0x81b7f34b),
+ TOBN(0xcf3dacf5, 0x1dc4ba75), TOBN(0x1d3d1773, 0xeb3310c7)},
+ {TOBN(0xa8e67112, 0x7747ae83), TOBN(0x31f43160, 0x197d6b40),
+ TOBN(0x0521ccee, 0xcd961400), TOBN(0x67246f11, 0xf6535768)}},
+ {{TOBN(0x702fcc5a, 0xef0c3133), TOBN(0x247cc45d, 0x7e16693b),
+ TOBN(0xfd484e49, 0xc729b749), TOBN(0x522cef7d, 0xb218320f)},
+ {TOBN(0xe56ef405, 0x59ab93b3), TOBN(0x225fba11, 0x9f181071),
+ TOBN(0x33bd6595, 0x15330ed0), TOBN(0xc4be69d5, 0x1ddb32f7)}},
+ {{TOBN(0x264c7668, 0x0448087c), TOBN(0xac30903f, 0x71432dae),
+ TOBN(0x3851b266, 0x00f9bf47), TOBN(0x400ed311, 0x6cdd6d03)},
+ {TOBN(0x045e79fe, 0xf8fd2424), TOBN(0xfdfd974a, 0xfa6da98b),
+ TOBN(0x45c9f641, 0x0c1e673a), TOBN(0x76f2e733, 0x5b2c5168)}},
+ {{TOBN(0x1adaebb5, 0x2a601753), TOBN(0xb286514c, 0xc57c2d49),
+ TOBN(0xd8769670, 0x1e0bfd24), TOBN(0x950c547e, 0x04478922)},
+ {TOBN(0xd1d41969, 0xe5d32bfe), TOBN(0x30bc1472, 0x750d6c3e),
+ TOBN(0x8f3679fe, 0xe0e27f3a), TOBN(0x8f64a7dc, 0xa4a6ee0c)}},
+ {{TOBN(0x2fe59937, 0x633dfb1f), TOBN(0xea82c395, 0x977f2547),
+ TOBN(0xcbdfdf1a, 0x661ea646), TOBN(0xc7ccc591, 0xb9085451)},
+ {TOBN(0x82177962, 0x81761e13), TOBN(0xda57596f, 0x9196885c),
+ TOBN(0xbc17e849, 0x28ffbd70), TOBN(0x1e6e0a41, 0x2671d36f)}},
+ {{TOBN(0x61ae872c, 0x4152fcf5), TOBN(0x441c87b0, 0x9e77e754),
+ TOBN(0xd0799dd5, 0xa34dff09), TOBN(0x766b4e44, 0x88a6b171)},
+ {TOBN(0xdc06a512, 0x11f1c792), TOBN(0xea02ae93, 0x4be35c3e),
+ TOBN(0xe5ca4d6d, 0xe90c469e), TOBN(0x4df4368e, 0x56e4ff5c)}},
+ {{TOBN(0x7817acab, 0x4baef62e), TOBN(0x9f5a2202, 0xa85b91e8),
+ TOBN(0x9666ebe6, 0x6ce57610), TOBN(0x32ad31f3, 0xf73bfe03)},
+ {TOBN(0x628330a4, 0x25bcf4d6), TOBN(0xea950593, 0x515056e6),
+ TOBN(0x59811c89, 0xe1332156), TOBN(0xc89cf1fe, 0x8c11b2d7)}},
+ {{TOBN(0x75b63913, 0x04e60cc0), TOBN(0xce811e8d, 0x4625d375),
+ TOBN(0x030e43fc, 0x2d26e562), TOBN(0xfbb30b4b, 0x608d36a0)},
+ {TOBN(0x634ff82c, 0x48528118), TOBN(0x7c6fe085, 0xcd285911),
+ TOBN(0x7f2830c0, 0x99358f28), TOBN(0x2e60a95e, 0x665e6c09)}},
+ {{TOBN(0x08407d3d, 0x9b785dbf), TOBN(0x530889ab, 0xa759bce7),
+ TOBN(0xf228e0e6, 0x52f61239), TOBN(0x2b6d1461, 0x6879be3c)},
+ {TOBN(0xe6902c04, 0x51a7bbf7), TOBN(0x30ad99f0, 0x76f24a64),
+ TOBN(0x66d9317a, 0x98bc6da0), TOBN(0xf4f877f3, 0xcb596ac0)}},
+ {{TOBN(0xb05ff62d, 0x4c44f119), TOBN(0x4555f536, 0xe9b77416),
+ TOBN(0xc7c0d059, 0x8caed63b), TOBN(0x0cd2b7ce, 0xc358b2a9)},
+ {TOBN(0x3f33287b, 0x46945fa3), TOBN(0xf8785b20, 0xd67c8791),
+ TOBN(0xc54a7a61, 0x9637bd08), TOBN(0x54d4598c, 0x18be79d7)}},
+ {{TOBN(0x889e5acb, 0xc46d7ce1), TOBN(0x9a515bb7, 0x8b085877),
+ TOBN(0xfac1a03d, 0x0b7a5050), TOBN(0x7d3e738a, 0xf2926035)},
+ {TOBN(0x861cc2ce, 0x2a6cb0eb), TOBN(0x6f2e2955, 0x8f7adc79),
+ TOBN(0x61c4d451, 0x33016376), TOBN(0xd9fd2c80, 0x5ad59090)}},
+ {{TOBN(0xe5a83738, 0xb2b836a1), TOBN(0x855b41a0, 0x7c0d6622),
+ TOBN(0x186fe317, 0x7cc19af1), TOBN(0x6465c1ff, 0xfdd99acb)},
+ {TOBN(0x46e5c23f, 0x6974b99e), TOBN(0x75a7cf8b, 0xa2717cbe),
+ TOBN(0x4d2ebc3f, 0x062be658), TOBN(0x094b4447, 0x5f209c98)}},
+ {{TOBN(0x4af285ed, 0xb940cb5a), TOBN(0x6706d792, 0x7cc82f10),
+ TOBN(0xc8c8776c, 0x030526fa), TOBN(0xfa8e6f76, 0xa0da9140)},
+ {TOBN(0x77ea9d34, 0x591ee4f0), TOBN(0x5f46e337, 0x40274166),
+ TOBN(0x1bdf98bb, 0xea671457), TOBN(0xd7c08b46, 0x862a1fe2)}},
+ {{TOBN(0x46cc303c, 0x1c08ad63), TOBN(0x99543440, 0x4c845e7b),
+ TOBN(0x1b8fbdb5, 0x48f36bf7), TOBN(0x5b82c392, 0x8c8273a7)},
+ {TOBN(0x08f712c4, 0x928435d5), TOBN(0x071cf0f1, 0x79330380),
+ TOBN(0xc74c2d24, 0xa8da054a), TOBN(0xcb0e7201, 0x43c46b5c)}},
+ {{TOBN(0x0ad7337a, 0xc0b7eff3), TOBN(0x8552225e, 0xc5e48b3c),
+ TOBN(0xe6f78b0c, 0x73f13a5f), TOBN(0x5e70062e, 0x82349cbe)},
+ {TOBN(0x6b8d5048, 0xe7073969), TOBN(0x392d2a29, 0xc33cb3d2),
+ TOBN(0xee4f727c, 0x4ecaa20f), TOBN(0xa068c99e, 0x2ccde707)}},
+ {{TOBN(0xfcd5651f, 0xb87a2913), TOBN(0xea3e3c15, 0x3cc252f0),
+ TOBN(0x777d92df, 0x3b6cd3e4), TOBN(0x7a414143, 0xc5a732e7)},
+ {TOBN(0xa895951a, 0xa71ff493), TOBN(0xfe980c92, 0xbbd37cf6),
+ TOBN(0x45bd5e64, 0xdecfeeff), TOBN(0x910dc2a9, 0xa44c43e9)}},
+ {{TOBN(0xcb403f26, 0xcca9f54d), TOBN(0x928bbdfb, 0x9303f6db),
+ TOBN(0x3c37951e, 0xa9eee67c), TOBN(0x3bd61a52, 0xf79961c3)},
+ {TOBN(0x09a238e6, 0x395c9a79), TOBN(0x6940ca2d, 0x61eb352d),
+ TOBN(0x7d1e5c5e, 0xc1875631), TOBN(0x1e19742c, 0x1e1b20d1)}},
+ {{TOBN(0x4633d908, 0x23fc2e6e), TOBN(0xa76e29a9, 0x08959149),
+ TOBN(0x61069d9c, 0x84ed7da5), TOBN(0x0baa11cf, 0x5dbcad51)},
+ {TOBN(0xd01eec64, 0x961849da), TOBN(0x93b75f1f, 0xaf3d8c28),
+ TOBN(0x57bc4f9f, 0x1ca2ee44), TOBN(0x5a26322d, 0x00e00558)}},
+ {{TOBN(0x1888d658, 0x61a023ef), TOBN(0x1d72aab4, 0xb9e5246e),
+ TOBN(0xa9a26348, 0xe5563ec0), TOBN(0xa0971963, 0xc3439a43)},
+ {TOBN(0x567dd54b, 0xadb9b5b7), TOBN(0x73fac1a1, 0xc45a524b),
+ TOBN(0x8fe97ef7, 0xfe38e608), TOBN(0x608748d2, 0x3f384f48)}},
+ {{TOBN(0xb0571794, 0xc486094f), TOBN(0x869254a3, 0x8bf3a8d6),
+ TOBN(0x148a8dd1, 0x310b0e25), TOBN(0x99ab9f3f, 0x9aa3f7d8)},
+ {TOBN(0x0927c68a, 0x6706c02e), TOBN(0x22b5e76c, 0x69790e6c),
+ TOBN(0x6c325260, 0x6c71376c), TOBN(0x53a57690, 0x09ef6657)}},
+ {{TOBN(0x8d63f852, 0xedffcf3a), TOBN(0xb4d2ed04, 0x3c0a6f55),
+ TOBN(0xdb3aa8de, 0x12519b9e), TOBN(0x5d38e9c4, 0x1e0a569a)},
+ {TOBN(0x871528bf, 0x303747e2), TOBN(0xa208e77c, 0xf5b5c18d),
+ TOBN(0x9d129c88, 0xca6bf923), TOBN(0xbcbf197f, 0xbf02839f)}},
+ {{TOBN(0x9b9bf030, 0x27323194), TOBN(0x3b055a8b, 0x339ca59d),
+ TOBN(0xb46b2312, 0x0f669520), TOBN(0x19789f1f, 0x497e5f24)},
+ {TOBN(0x9c499468, 0xaaf01801), TOBN(0x72ee1190, 0x8b69d59c),
+ TOBN(0x8bd39595, 0xacf4c079), TOBN(0x3ee11ece, 0x8e0cd048)}},
+ {{TOBN(0xebde86ec, 0x1ed66f18), TOBN(0x225d906b, 0xd61fce43),
+ TOBN(0x5cab07d6, 0xe8bed74d), TOBN(0x16e4617f, 0x27855ab7)},
+ {TOBN(0x6568aadd, 0xb2fbc3dd), TOBN(0xedb5484f, 0x8aeddf5b),
+ TOBN(0x878f20e8, 0x6dcf2fad), TOBN(0x3516497c, 0x615f5699)}}},
+ {{{TOBN(0xef0a3fec, 0xfa181e69), TOBN(0x9ea02f81, 0x30d69a98),
+ TOBN(0xb2e9cf8e, 0x66eab95d), TOBN(0x520f2beb, 0x24720021)},
+ {TOBN(0x621c540a, 0x1df84361), TOBN(0x12037721, 0x71fa6d5d),
+ TOBN(0x6e3c7b51, 0x0ff5f6ff), TOBN(0x817a069b, 0xabb2bef3)}},
+ {{TOBN(0x83572fb6, 0xb294cda6), TOBN(0x6ce9bf75, 0xb9039f34),
+ TOBN(0x20e012f0, 0x095cbb21), TOBN(0xa0aecc1b, 0xd063f0da)},
+ {TOBN(0x57c21c3a, 0xf02909e5), TOBN(0xc7d59ecf, 0x48ce9cdc),
+ TOBN(0x2732b844, 0x8ae336f8), TOBN(0x056e3723, 0x3f4f85f4)}},
+ {{TOBN(0x8a10b531, 0x89e800ca), TOBN(0x50fe0c17, 0x145208fd),
+ TOBN(0x9e43c0d3, 0xb714ba37), TOBN(0x427d200e, 0x34189acc)},
+ {TOBN(0x05dee24f, 0xe616e2c0), TOBN(0x9c25f4c8, 0xee1854c1),
+ TOBN(0x4d3222a5, 0x8f342a73), TOBN(0x0807804f, 0xa027c952)}},
+ {{TOBN(0xc222653a, 0x4f0d56f3), TOBN(0x961e4047, 0xca28b805),
+ TOBN(0x2c03f8b0, 0x4a73434b), TOBN(0x4c966787, 0xab712a19)},
+ {TOBN(0xcc196c42, 0x864fee42), TOBN(0xc1be93da, 0x5b0ece5c),
+ TOBN(0xa87d9f22, 0xc131c159), TOBN(0x2bb6d593, 0xdce45655)}},
+ {{TOBN(0x22c49ec9, 0xb809b7ce), TOBN(0x8a41486b, 0xe2c72c2c),
+ TOBN(0x813b9420, 0xfea0bf36), TOBN(0xb3d36ee9, 0xa66dac69)},
+ {TOBN(0x6fddc08a, 0x328cc987), TOBN(0x0a3bcd2c, 0x3a326461),
+ TOBN(0x7103c49d, 0xd810dbba), TOBN(0xf9d81a28, 0x4b78a4c4)}},
+ {{TOBN(0x3de865ad, 0xe4d55941), TOBN(0xdedafa5e, 0x30384087),
+ TOBN(0x6f414abb, 0x4ef18b9b), TOBN(0x9ee9ea42, 0xfaee5268)},
+ {TOBN(0x260faa16, 0x37a55a4a), TOBN(0xeb19a514, 0x015f93b9),
+ TOBN(0x51d7ebd2, 0x9e9c3598), TOBN(0x523fc56d, 0x1932178e)}},
+ {{TOBN(0x501d070c, 0xb98fe684), TOBN(0xd60fbe9a, 0x124a1458),
+ TOBN(0xa45761c8, 0x92bc6b3f), TOBN(0xf5384858, 0xfe6f27cb)},
+ {TOBN(0x4b0271f7, 0xb59e763b), TOBN(0x3d4606a9, 0x5b5a8e5e),
+ TOBN(0x1eda5d9b, 0x05a48292), TOBN(0xda7731d0, 0xe6fec446)}},
+ {{TOBN(0xa3e33693, 0x90d45871), TOBN(0xe9764040, 0x06166d8d),
+ TOBN(0xb5c33682, 0x89a90403), TOBN(0x4bd17983, 0x72f1d637)},
+ {TOBN(0xa616679e, 0xd5d2c53a), TOBN(0x5ec4bcd8, 0xfdcf3b87),
+ TOBN(0xae6d7613, 0xb66a694e), TOBN(0x7460fc76, 0xe3fc27e5)}},
+ {{TOBN(0x70469b82, 0x95caabee), TOBN(0xde024ca5, 0x889501e3),
+ TOBN(0x6bdadc06, 0x076ed265), TOBN(0x0cb1236b, 0x5a0ef8b2)},
+ {TOBN(0x4065ddbf, 0x0972ebf9), TOBN(0xf1dd3875, 0x22aca432),
+ TOBN(0xa88b97cf, 0x744aff76), TOBN(0xd1359afd, 0xfe8e3d24)}},
+ {{TOBN(0x52a3ba2b, 0x91502cf3), TOBN(0x2c3832a8, 0x084db75d),
+ TOBN(0x04a12ddd, 0xde30b1c9), TOBN(0x7802eabc, 0xe31fd60c)},
+ {TOBN(0x33707327, 0xa37fddab), TOBN(0x65d6f2ab, 0xfaafa973),
+ TOBN(0x3525c5b8, 0x11e6f91a), TOBN(0x76aeb0c9, 0x5f46530b)}},
+ {{TOBN(0xe8815ff6, 0x2f93a675), TOBN(0xa6ec9684, 0x05f48679),
+ TOBN(0x6dcbb556, 0x358ae884), TOBN(0x0af61472, 0xe19e3873)},
+ {TOBN(0x72334372, 0xa5f696be), TOBN(0xc65e57ea, 0x6f22fb70),
+ TOBN(0x268da30c, 0x946cea90), TOBN(0x136a8a87, 0x65681b2a)}},
+ {{TOBN(0xad5e81dc, 0x0f9f44d4), TOBN(0xf09a6960, 0x2c46585a),
+ TOBN(0xd1649164, 0xc447d1b1), TOBN(0x3b4b36c8, 0x879dc8b1)},
+ {TOBN(0x20d4177b, 0x3b6b234c), TOBN(0x096a2505, 0x1730d9d0),
+ TOBN(0x0611b9b8, 0xef80531d), TOBN(0xba904b3b, 0x64bb495d)}},
+ {{TOBN(0x1192d9d4, 0x93a3147a), TOBN(0x9f30a5dc, 0x9a565545),
+ TOBN(0x90b1f9cb, 0x6ef07212), TOBN(0x29958546, 0x0d87fc13)},
+ {TOBN(0xd3323eff, 0xc17db9ba), TOBN(0xcb18548c, 0xcb1644a8),
+ TOBN(0x18a306d4, 0x4f49ffbc), TOBN(0x28d658f1, 0x4c2e8684)}},
+ {{TOBN(0x44ba60cd, 0xa99f8c71), TOBN(0x67b7abdb, 0x4bf742ff),
+ TOBN(0x66310f9c, 0x914b3f99), TOBN(0xae430a32, 0xf412c161)},
+ {TOBN(0x1e6776d3, 0x88ace52f), TOBN(0x4bc0fa24, 0x52d7067d),
+ TOBN(0x03c286aa, 0x8f07cd1b), TOBN(0x4cb8f38c, 0xa985b2c1)}},
+ {{TOBN(0x83ccbe80, 0x8c3bff36), TOBN(0x005a0bd2, 0x5263e575),
+ TOBN(0x460d7dda, 0x259bdcd1), TOBN(0x4a1c5642, 0xfa5cab6b)},
+ {TOBN(0x2b7bdbb9, 0x9fe4fc88), TOBN(0x09418e28, 0xcc97bbb5),
+ TOBN(0xd8274fb4, 0xa12321ae), TOBN(0xb137007d, 0x5c87b64e)}},
+ {{TOBN(0x80531fe1, 0xc63c4962), TOBN(0x50541e89, 0x981fdb25),
+ TOBN(0xdc1291a1, 0xfd4c2b6b), TOBN(0xc0693a17, 0xa6df4fca)},
+ {TOBN(0xb2c4604e, 0x0117f203), TOBN(0x245f1963, 0x0a99b8d0),
+ TOBN(0xaedc20aa, 0xc6212c44), TOBN(0xb1ed4e56, 0x520f52a8)}},
+ {{TOBN(0xfe48f575, 0xf8547be3), TOBN(0x0a7033cd, 0xa9e45f98),
+ TOBN(0x4b45d3a9, 0x18c50100), TOBN(0xb2a6cd6a, 0xa61d41da)},
+ {TOBN(0x60bbb4f5, 0x57933c6b), TOBN(0xa7538ebd, 0x2b0d7ffc),
+ TOBN(0x9ea3ab8d, 0x8cd626b6), TOBN(0x8273a484, 0x3601625a)}},
+ {{TOBN(0x88859845, 0x0168e508), TOBN(0x8cbc9bb2, 0x99a94abd),
+ TOBN(0x713ac792, 0xfab0a671), TOBN(0xa3995b19, 0x6c9ebffc)},
+ {TOBN(0xe711668e, 0x1239e152), TOBN(0x56892558, 0xbbb8dff4),
+ TOBN(0x8bfc7dab, 0xdbf17963), TOBN(0x5b59fe5a, 0xb3de1253)}},
+ {{TOBN(0x7e3320eb, 0x34a9f7ae), TOBN(0xe5e8cf72, 0xd751efe4),
+ TOBN(0x7ea003bc, 0xd9be2f37), TOBN(0xc0f551a0, 0xb6c08ef7)},
+ {TOBN(0x56606268, 0x038f6725), TOBN(0x1dd38e35, 0x6d92d3b6),
+ TOBN(0x07dfce7c, 0xc3cbd686), TOBN(0x4e549e04, 0x651c5da8)}},
+ {{TOBN(0x4058f93b, 0x08b19340), TOBN(0xc2fae6f4, 0xcac6d89d),
+ TOBN(0x4bad8a8c, 0x8f159cc7), TOBN(0x0ddba4b3, 0xcb0b601c)},
+ {TOBN(0xda4fc7b5, 0x1dd95f8c), TOBN(0x1d163cd7, 0xcea5c255),
+ TOBN(0x30707d06, 0x274a8c4c), TOBN(0x79d9e008, 0x2802e9ce)}},
+ {{TOBN(0x02a29ebf, 0xe6ddd505), TOBN(0x37064e74, 0xb50bed1a),
+ TOBN(0x3f6bae65, 0xa7327d57), TOBN(0x3846f5f1, 0xf83920bc)},
+ {TOBN(0x87c37491, 0x60df1b9b), TOBN(0x4cfb2895, 0x2d1da29f),
+ TOBN(0x10a478ca, 0x4ed1743c), TOBN(0x390c6030, 0x3edd47c6)}},
+ {{TOBN(0x8f3e5312, 0x8c0a78de), TOBN(0xccd02bda, 0x1e85df70),
+ TOBN(0xd6c75c03, 0xa61b6582), TOBN(0x0762921c, 0xfc0eebd1)},
+ {TOBN(0xd34d0823, 0xd85010c0), TOBN(0xd73aaacb, 0x0044cf1f),
+ TOBN(0xfb4159bb, 0xa3b5e78a), TOBN(0x2287c7f7, 0xe5826f3f)}},
+ {{TOBN(0x4aeaf742, 0x580b1a01), TOBN(0xf080415d, 0x60423b79),
+ TOBN(0xe12622cd, 0xa7dea144), TOBN(0x49ea4996, 0x59d62472)},
+ {TOBN(0xb42991ef, 0x571f3913), TOBN(0x0610f214, 0xf5b25a8a),
+ TOBN(0x47adc585, 0x30b79e8f), TOBN(0xf90e3df6, 0x07a065a2)}},
+ {{TOBN(0x5d0a5deb, 0x43e2e034), TOBN(0x53fb5a34, 0x444024aa),
+ TOBN(0xa8628c68, 0x6b0c9f7f), TOBN(0x9c69c29c, 0xac563656)},
+ {TOBN(0x5a231feb, 0xbace47b6), TOBN(0xbdce0289, 0x9ea5a2ec),
+ TOBN(0x05da1fac, 0x9463853e), TOBN(0x96812c52, 0x509e78aa)}},
+ {{TOBN(0xd3fb5771, 0x57151692), TOBN(0xeb2721f8, 0xd98e1c44),
+ TOBN(0xc0506087, 0x32399be1), TOBN(0xda5a5511, 0xd979d8b8)},
+ {TOBN(0x737ed55d, 0xc6f56780), TOBN(0xe20d3004, 0x0dc7a7f4),
+ TOBN(0x02ce7301, 0xf5941a03), TOBN(0x91ef5215, 0xed30f83a)}},
+ {{TOBN(0x28727fc1, 0x4092d85f), TOBN(0x72d223c6, 0x5c49e41a),
+ TOBN(0xa7cf30a2, 0xba6a4d81), TOBN(0x7c086209, 0xb030d87d)},
+ {TOBN(0x04844c7d, 0xfc588b09), TOBN(0x728cd499, 0x5874bbb0),
+ TOBN(0xcc1281ee, 0xe84c0495), TOBN(0x0769b5ba, 0xec31958f)}},
+ {{TOBN(0x665c228b, 0xf99c2471), TOBN(0xf2d8a11b, 0x191eb110),
+ TOBN(0x4594f494, 0xd36d7024), TOBN(0x482ded8b, 0xcdcb25a1)},
+ {TOBN(0xc958a9d8, 0xdadd4885), TOBN(0x7004477e, 0xf1d2b547),
+ TOBN(0x0a45f6ef, 0x2a0af550), TOBN(0x4fc739d6, 0x2f8d6351)}},
+ {{TOBN(0x75cdaf27, 0x786f08a9), TOBN(0x8700bb26, 0x42c2737f),
+ TOBN(0x855a7141, 0x1c4e2670), TOBN(0x810188c1, 0x15076fef)},
+ {TOBN(0xc251d0c9, 0xabcd3297), TOBN(0xae4c8967, 0xf48108eb),
+ TOBN(0xbd146de7, 0x18ceed30), TOBN(0xf9d4f07a, 0xc986bced)}},
+ {{TOBN(0x5ad98ed5, 0x83fa1e08), TOBN(0x7780d33e, 0xbeabd1fb),
+ TOBN(0xe330513c, 0x903b1196), TOBN(0xba11de9e, 0xa47bc8c4)},
+ {TOBN(0x684334da, 0x02c2d064), TOBN(0x7ecf360d, 0xa48de23b),
+ TOBN(0x57a1b474, 0x0a9089d8), TOBN(0xf28fa439, 0xff36734c)}},
+ {{TOBN(0xf2a482cb, 0xea4570b3), TOBN(0xee65d68b, 0xa5ebcee9),
+ TOBN(0x988d0036, 0xb9694cd5), TOBN(0x53edd0e9, 0x37885d32)},
+ {TOBN(0xe37e3307, 0xbeb9bc6d), TOBN(0xe9abb907, 0x9f5c6768),
+ TOBN(0x4396ccd5, 0x51f2160f), TOBN(0x2500888c, 0x47336da6)}},
+ {{TOBN(0x383f9ed9, 0x926fce43), TOBN(0x809dd1c7, 0x04da2930),
+ TOBN(0x30f6f596, 0x8a4cb227), TOBN(0x0d700c7f, 0x73a56b38)},
+ {TOBN(0x1825ea33, 0xab64a065), TOBN(0xaab9b735, 0x1338df80),
+ TOBN(0x1516100d, 0x9b63f57f), TOBN(0x2574395a, 0x27a6a634)}},
+ {{TOBN(0xb5560fb6, 0x700a1acd), TOBN(0xe823fd73, 0xfd999681),
+ TOBN(0xda915d1f, 0x6cb4e1ba), TOBN(0x0d030118, 0x6ebe00a3)},
+ {TOBN(0x744fb0c9, 0x89fca8cd), TOBN(0x970d01db, 0xf9da0e0b),
+ TOBN(0x0ad8c564, 0x7931d76f), TOBN(0xb15737bf, 0xf659b96a)}},
+ {{TOBN(0xdc9933e8, 0xa8b484e7), TOBN(0xb2fdbdf9, 0x7a26dec7),
+ TOBN(0x2349e9a4, 0x9f1f0136), TOBN(0x7860368e, 0x70fddddb)},
+ {TOBN(0xd93d2c1c, 0xf9ad3e18), TOBN(0x6d6c5f17, 0x689f4e79),
+ TOBN(0x7a544d91, 0xb24ff1b6), TOBN(0x3e12a5eb, 0xfe16cd8c)}},
+ {{TOBN(0x543574e9, 0xa56b872f), TOBN(0xa1ad550c, 0xfcf68ea2),
+ TOBN(0x689e37d2, 0x3f560ef7), TOBN(0x8c54b9ca, 0xc9d47a8b)},
+ {TOBN(0x46d40a4a, 0x088ac342), TOBN(0xec450c7c, 0x1576c6d0),
+ TOBN(0xb589e31c, 0x1f9689e9), TOBN(0xdacf2602, 0xb8781718)}},
+ {{TOBN(0xa89237c6, 0xc8cb6b42), TOBN(0x1326fc93, 0xb96ef381),
+ TOBN(0x55d56c6d, 0xb5f07825), TOBN(0xacba2eea, 0x7449e22d)},
+ {TOBN(0x74e0887a, 0x633c3000), TOBN(0xcb6cd172, 0xd7cbcf71),
+ TOBN(0x309e81de, 0xc36cf1be), TOBN(0x07a18a6d, 0x60ae399b)}},
+ {{TOBN(0xb36c2679, 0x9edce57e), TOBN(0x52b892f4, 0xdf001d41),
+ TOBN(0xd884ae5d, 0x16a1f2c6), TOBN(0x9b329424, 0xefcc370a)},
+ {TOBN(0x3120daf2, 0xbd2e21df), TOBN(0x55298d2d, 0x02470a99),
+ TOBN(0x0b78af6c, 0xa05db32e), TOBN(0x5c76a331, 0x601f5636)}},
+ {{TOBN(0xaae861ff, 0xf8a4f29c), TOBN(0x70dc9240, 0xd68f8d49),
+ TOBN(0x960e649f, 0x81b1321c), TOBN(0x3d2c801b, 0x8792e4ce)},
+ {TOBN(0xf479f772, 0x42521876), TOBN(0x0bed93bc, 0x416c79b1),
+ TOBN(0xa67fbc05, 0x263e5bc9), TOBN(0x01e8e630, 0x521db049)}},
+ {{TOBN(0x76f26738, 0xc6f3431e), TOBN(0xe609cb02, 0xe3267541),
+ TOBN(0xb10cff2d, 0x818c877c), TOBN(0x1f0e75ce, 0x786a13cb)},
+ {TOBN(0xf4fdca64, 0x1158544d), TOBN(0x5d777e89, 0x6cb71ed0),
+ TOBN(0x3c233737, 0xa9aa4755), TOBN(0x7b453192, 0xe527ab40)}},
+ {{TOBN(0xdb59f688, 0x39f05ffe), TOBN(0x8f4f4be0, 0x6d82574e),
+ TOBN(0xcce3450c, 0xee292d1b), TOBN(0xaa448a12, 0x61ccd086)},
+ {TOBN(0xabce91b3, 0xf7914967), TOBN(0x4537f09b, 0x1908a5ed),
+ TOBN(0xa812421e, 0xf51042e7), TOBN(0xfaf5cebc, 0xec0b3a34)}},
+ {{TOBN(0x730ffd87, 0x4ca6b39a), TOBN(0x70fb72ed, 0x02efd342),
+ TOBN(0xeb4735f9, 0xd75c8edb), TOBN(0xc11f2157, 0xc278aa51)},
+ {TOBN(0xc459f635, 0xbf3bfebf), TOBN(0x3a1ff0b4, 0x6bd9601f),
+ TOBN(0xc9d12823, 0xc420cb73), TOBN(0x3e9af3e2, 0x3c2915a3)}},
+ {{TOBN(0xe0c82c72, 0xb41c3440), TOBN(0x175239e5, 0xe3039a5f),
+ TOBN(0xe1084b8a, 0x558795a3), TOBN(0x328d0a1d, 0xd01e5c60)},
+ {TOBN(0x0a495f2e, 0xd3788a04), TOBN(0x25d8ff16, 0x66c11a9f),
+ TOBN(0xf5155f05, 0x9ed692d6), TOBN(0x954fa107, 0x4f425fe4)}},
+ {{TOBN(0xd16aabf2, 0xe98aaa99), TOBN(0x90cd8ba0, 0x96b0f88a),
+ TOBN(0x957f4782, 0xc154026a), TOBN(0x54ee0734, 0x52af56d2)},
+ {TOBN(0xbcf89e54, 0x45b4147a), TOBN(0x3d102f21, 0x9a52816c),
+ TOBN(0x6808517e, 0x39b62e77), TOBN(0x92e25421, 0x69169ad8)}},
+ {{TOBN(0xd721d871, 0xbb608558), TOBN(0x60e4ebae, 0xf6d4ff9b),
+ TOBN(0x0ba10819, 0x41f2763e), TOBN(0xca2e45be, 0x51ee3247)},
+ {TOBN(0x66d172ec, 0x2bfd7a5f), TOBN(0x528a8f2f, 0x74d0b12d),
+ TOBN(0xe17f1e38, 0xdabe70dc), TOBN(0x1d5d7316, 0x9f93983c)}},
+ {{TOBN(0x51b2184a, 0xdf423e31), TOBN(0xcb417291, 0xaedb1a10),
+ TOBN(0x2054ca93, 0x625bcab9), TOBN(0x54396860, 0xa98998f0)},
+ {TOBN(0x4e53f6c4, 0xa54ae57e), TOBN(0x0ffeb590, 0xee648e9d),
+ TOBN(0xfbbdaadc, 0x6afaf6bc), TOBN(0xf88ae796, 0xaa3bfb8a)}},
+ {{TOBN(0x209f1d44, 0xd2359ed9), TOBN(0xac68dd03, 0xf3544ce2),
+ TOBN(0xf378da47, 0xfd51e569), TOBN(0xe1abd860, 0x2cc80097)},
+ {TOBN(0x23ca18d9, 0x343b6e3a), TOBN(0x480797e8, 0xb40a1bae),
+ TOBN(0xd1f0c717, 0x533f3e67), TOBN(0x44896970, 0x06e6cdfc)}},
+ {{TOBN(0x8ca21055, 0x52a82e8d), TOBN(0xb2caf785, 0x78460cdc),
+ TOBN(0x4c1b7b62, 0xe9037178), TOBN(0xefc09d2c, 0xdb514b58)},
+ {TOBN(0x5f2df9ee, 0x9113be5c), TOBN(0x2fbda78f, 0xb3f9271c),
+ TOBN(0xe09a81af, 0x8f83fc54), TOBN(0x06b13866, 0x8afb5141)}},
+ {{TOBN(0x38f6480f, 0x43e3865d), TOBN(0x72dd77a8, 0x1ddf47d9),
+ TOBN(0xf2a8e971, 0x4c205ff7), TOBN(0x46d449d8, 0x9d088ad8)},
+ {TOBN(0x926619ea, 0x185d706f), TOBN(0xe47e02eb, 0xc7dd7f62),
+ TOBN(0xe7f120a7, 0x8cbc2031), TOBN(0xc18bef00, 0x998d4ac9)}},
+ {{TOBN(0x18f37a9c, 0x6bdf22da), TOBN(0xefbc432f, 0x90dc82df),
+ TOBN(0xc52cef8e, 0x5d703651), TOBN(0x82887ba0, 0xd99881a5)},
+ {TOBN(0x7cec9dda, 0xb920ec1d), TOBN(0xd0d7e8c3, 0xec3e8d3b),
+ TOBN(0x445bc395, 0x4ca88747), TOBN(0xedeaa2e0, 0x9fd53535)}},
+ {{TOBN(0x461b1d93, 0x6cc87475), TOBN(0xd92a52e2, 0x6d2383bd),
+ TOBN(0xfabccb59, 0xd7903546), TOBN(0x6111a761, 0x3d14b112)},
+ {TOBN(0x0ae584fe, 0xb3d5f612), TOBN(0x5ea69b8d, 0x60e828ec),
+ TOBN(0x6c078985, 0x54087030), TOBN(0x649cab04, 0xac4821fe)}},
+ {{TOBN(0x25ecedcf, 0x8bdce214), TOBN(0xb5622f72, 0x86af7361),
+ TOBN(0x0e1227aa, 0x7038b9e2), TOBN(0xd0efb273, 0xac20fa77)},
+ {TOBN(0x817ff88b, 0x79df975b), TOBN(0x856bf286, 0x1999503e),
+ TOBN(0xb4d5351f, 0x5038ec46), TOBN(0x740a52c5, 0xfc42af6e)}},
+ {{TOBN(0x2e38bb15, 0x2cbb1a3f), TOBN(0xc3eb99fe, 0x17a83429),
+ TOBN(0xca4fcbf1, 0xdd66bb74), TOBN(0x880784d6, 0xcde5e8fc)},
+ {TOBN(0xddc84c1c, 0xb4e7a0be), TOBN(0x8780510d, 0xbd15a72f),
+ TOBN(0x44bcf1af, 0x81ec30e1), TOBN(0x141e50a8, 0x0a61073e)}},
+ {{TOBN(0x0d955718, 0x47be87ae), TOBN(0x68a61417, 0xf76a4372),
+ TOBN(0xf57e7e87, 0xc607c3d3), TOBN(0x043afaf8, 0x5252f332)},
+ {TOBN(0xcc14e121, 0x1552a4d2), TOBN(0xb6dee692, 0xbb4d4ab4),
+ TOBN(0xb6ab74c8, 0xa03816a4), TOBN(0x84001ae4, 0x6f394a29)}},
+ {{TOBN(0x5bed8344, 0xd795fb45), TOBN(0x57326e7d, 0xb79f55a5),
+ TOBN(0xc9533ce0, 0x4accdffc), TOBN(0x53473caf, 0x3993fa04)},
+ {TOBN(0x7906eb93, 0xa13df4c8), TOBN(0xa73e51f6, 0x97cbe46f),
+ TOBN(0xd1ab3ae1, 0x0ae4ccf8), TOBN(0x25614508, 0x8a5b3dbc)}},
+ {{TOBN(0x61eff962, 0x11a71b27), TOBN(0xdf71412b, 0x6bb7fa39),
+ TOBN(0xb31ba6b8, 0x2bd7f3ef), TOBN(0xb0b9c415, 0x69180d29)},
+ {TOBN(0xeec14552, 0x014cdde5), TOBN(0x702c624b, 0x227b4bbb),
+ TOBN(0x2b15e8c2, 0xd3e988f3), TOBN(0xee3bcc6d, 0xa4f7fd04)}},
+ {{TOBN(0x9d00822a, 0x42ac6c85), TOBN(0x2db0cea6, 0x1df9f2b7),
+ TOBN(0xd7cad2ab, 0x42de1e58), TOBN(0x346ed526, 0x2d6fbb61)},
+ {TOBN(0xb3962995, 0x1a2faf09), TOBN(0x2fa8a580, 0x7c25612e),
+ TOBN(0x30ae04da, 0x7cf56490), TOBN(0x75662908, 0x0eea3961)}},
+ {{TOBN(0x3609f5c5, 0x3d080847), TOBN(0xcb081d39, 0x5241d4f6),
+ TOBN(0xb4fb3810, 0x77961a63), TOBN(0xc20c5984, 0x2abb66fc)},
+ {TOBN(0x3d40aa7c, 0xf902f245), TOBN(0x9cb12736, 0x4e536b1e),
+ TOBN(0x5eda24da, 0x99b3134f), TOBN(0xafbd9c69, 0x5cd011af)}},
+ {{TOBN(0x9a16e30a, 0xc7088c7d), TOBN(0x5ab65710, 0x3207389f),
+ TOBN(0x1b09547f, 0xe7407a53), TOBN(0x2322f9d7, 0x4fdc6eab)},
+ {TOBN(0xc0f2f22d, 0x7430de4d), TOBN(0x19382696, 0xe68ca9a9),
+ TOBN(0x17f1eff1, 0x918e5868), TOBN(0xe3b5b635, 0x586f4204)}},
+ {{TOBN(0x146ef980, 0x3fbc4341), TOBN(0x359f2c80, 0x5b5eed4e),
+ TOBN(0x9f35744e, 0x7482e41d), TOBN(0x9a9ac3ec, 0xf3b224c2)},
+ {TOBN(0x9161a6fe, 0x91fc50ae), TOBN(0x89ccc66b, 0xc613fa7c),
+ TOBN(0x89268b14, 0xc732f15a), TOBN(0x7cd6f4e2, 0xb467ed03)}},
+ {{TOBN(0xfbf79869, 0xce56b40e), TOBN(0xf93e094c, 0xc02dde98),
+ TOBN(0xefe0c3a8, 0xedee2cd7), TOBN(0x90f3ffc0, 0xb268fd42)},
+ {TOBN(0x81a7fd56, 0x08241aed), TOBN(0x95ab7ad8, 0x00b1afe8),
+ TOBN(0x40127056, 0x3e310d52), TOBN(0xd3ffdeb1, 0x09d9fc43)}},
+ {{TOBN(0xc8f85c91, 0xd11a8594), TOBN(0x2e74d258, 0x31cf6db8),
+ TOBN(0x829c7ca3, 0x02b5dfd0), TOBN(0xe389cfbe, 0x69143c86)},
+ {TOBN(0xd01b6405, 0x941768d8), TOBN(0x45103995, 0x03bf825d),
+ TOBN(0xcc4ee166, 0x56cd17e2), TOBN(0xbea3c283, 0xba037e79)}},
+ {{TOBN(0x4e1ac06e, 0xd9a47520), TOBN(0xfbfe18aa, 0xaf852404),
+ TOBN(0x5615f8e2, 0x8087648a), TOBN(0x7301e47e, 0xb9d150d9)},
+ {TOBN(0x79f9f9dd, 0xb299b977), TOBN(0x76697a7b, 0xa5b78314),
+ TOBN(0x10d67468, 0x7d7c90e7), TOBN(0x7afffe03, 0x937210b5)}},
+ {{TOBN(0x5aef3e4b, 0x28c22cee), TOBN(0xefb0ecd8, 0x09fd55ae),
+ TOBN(0x4cea7132, 0x0d2a5d6a), TOBN(0x9cfb5fa1, 0x01db6357)},
+ {TOBN(0x395e0b57, 0xf36e1ac5), TOBN(0x008fa9ad, 0x36cafb7d),
+ TOBN(0x8f6cdf70, 0x5308c4db), TOBN(0x51527a37, 0x95ed2477)}},
+ {{TOBN(0xba0dee30, 0x5bd21311), TOBN(0x6ed41b22, 0x909c90d7),
+ TOBN(0xc5f6b758, 0x7c8696d3), TOBN(0x0db8eaa8, 0x3ce83a80)},
+ {TOBN(0xd297fe37, 0xb24b4b6f), TOBN(0xfe58afe8, 0x522d1f0d),
+ TOBN(0x97358736, 0x8c98dbd9), TOBN(0x6bc226ca, 0x9454a527)}},
+ {{TOBN(0xa12b384e, 0xce53c2d0), TOBN(0x779d897d, 0x5e4606da),
+ TOBN(0xa53e47b0, 0x73ec12b0), TOBN(0x462dbbba, 0x5756f1ad)},
+ {TOBN(0x69fe09f2, 0xcafe37b6), TOBN(0x273d1ebf, 0xecce2e17),
+ TOBN(0x8ac1d538, 0x3cf607fd), TOBN(0x8035f7ff, 0x12e10c25)}}},
+ {{{TOBN(0x854d34c7, 0x7e6c5520), TOBN(0xc27df9ef, 0xdcb9ea58),
+ TOBN(0x405f2369, 0xd686666d), TOBN(0x29d1febf, 0x0417aa85)},
+ {TOBN(0x9846819e, 0x93470afe), TOBN(0x3e6a9669, 0xe2a27f9e),
+ TOBN(0x24d008a2, 0xe31e6504), TOBN(0xdba7cecf, 0x9cb7680a)}},
+ {{TOBN(0xecaff541, 0x338d6e43), TOBN(0x56f7dd73, 0x4541d5cc),
+ TOBN(0xb5d426de, 0x96bc88ca), TOBN(0x48d94f6b, 0x9ed3a2c3)},
+ {TOBN(0x6354a3bb, 0x2ef8279c), TOBN(0xd575465b, 0x0b1867f2),
+ TOBN(0xef99b0ff, 0x95225151), TOBN(0xf3e19d88, 0xf94500d8)}},
+ {{TOBN(0x92a83268, 0xe32dd620), TOBN(0x913ec99f, 0x627849a2),
+ TOBN(0xedd8fdfa, 0x2c378882), TOBN(0xaf96f33e, 0xee6f8cfe)},
+ {TOBN(0xc06737e5, 0xdc3fa8a5), TOBN(0x236bb531, 0xb0b03a1d),
+ TOBN(0x33e59f29, 0x89f037b0), TOBN(0x13f9b5a7, 0xd9a12a53)}},
+ {{TOBN(0x0d0df6ce, 0x51efb310), TOBN(0xcb5b2eb4, 0x958df5be),
+ TOBN(0xd6459e29, 0x36158e59), TOBN(0x82aae2b9, 0x1466e336)},
+ {TOBN(0xfb658a39, 0x411aa636), TOBN(0x7152ecc5, 0xd4c0a933),
+ TOBN(0xf10c758a, 0x49f026b7), TOBN(0xf4837f97, 0xcb09311f)}},
+ {{TOBN(0xddfb02c4, 0xc753c45f), TOBN(0x18ca81b6, 0xf9c840fe),
+ TOBN(0x846fd09a, 0xb0f8a3e6), TOBN(0xb1162add, 0xe7733dbc)},
+ {TOBN(0x7070ad20, 0x236e3ab6), TOBN(0xf88cdaf5, 0xb2a56326),
+ TOBN(0x05fc8719, 0x997cbc7a), TOBN(0x442cd452, 0x4b665272)}},
+ {{TOBN(0x7807f364, 0xb71698f5), TOBN(0x6ba418d2, 0x9f7b605e),
+ TOBN(0xfd20b00f, 0xa03b2cbb), TOBN(0x883eca37, 0xda54386f)},
+ {TOBN(0xff0be43f, 0xf3437f24), TOBN(0xe910b432, 0xa48bb33c),
+ TOBN(0x4963a128, 0x329df765), TOBN(0xac1dd556, 0xbe2fe6f7)}},
+ {{TOBN(0x557610f9, 0x24a0a3fc), TOBN(0x38e17bf4, 0xe881c3f9),
+ TOBN(0x6ba84faf, 0xed0dac99), TOBN(0xd4a222c3, 0x59eeb918)},
+ {TOBN(0xc79c1dbe, 0x13f542b6), TOBN(0x1fc65e0d, 0xe425d457),
+ TOBN(0xeffb754f, 0x1debb779), TOBN(0x638d8fd0, 0x9e08af60)}},
+ {{TOBN(0x994f523a, 0x626332d5), TOBN(0x7bc38833, 0x5561bb44),
+ TOBN(0x005ed4b0, 0x3d845ea2), TOBN(0xd39d3ee1, 0xc2a1f08a)},
+ {TOBN(0x6561fdd3, 0xe7676b0d), TOBN(0x620e35ff, 0xfb706017),
+ TOBN(0x36ce424f, 0xf264f9a8), TOBN(0xc4c3419f, 0xda2681f7)}},
+ {{TOBN(0xfb6afd2f, 0x69beb6e8), TOBN(0x3a50b993, 0x6d700d03),
+ TOBN(0xc840b2ad, 0x0c83a14f), TOBN(0x573207be, 0x54085bef)},
+ {TOBN(0x5af882e3, 0x09fe7e5b), TOBN(0x957678a4, 0x3b40a7e1),
+ TOBN(0x172d4bdd, 0x543056e2), TOBN(0x9c1b26b4, 0x0df13c0a)}},
+ {{TOBN(0x1c30861c, 0xf405ff06), TOBN(0xebac86bd, 0x486e828b),
+ TOBN(0xe791a971, 0x636933fc), TOBN(0x50e7c2be, 0x7aeee947)},
+ {TOBN(0xc3d4a095, 0xfa90d767), TOBN(0xae60eb7b, 0xe670ab7b),
+ TOBN(0x17633a64, 0x397b056d), TOBN(0x93a21f33, 0x105012aa)}},
+ {{TOBN(0x663c370b, 0xabb88643), TOBN(0x91df36d7, 0x22e21599),
+ TOBN(0x183ba835, 0x8b761671), TOBN(0x381eea1d, 0x728f3bf1)},
+ {TOBN(0xb9b2f1ba, 0x39966e6c), TOBN(0x7c464a28, 0xe7295492),
+ TOBN(0x0fd5f70a, 0x09b26b7f), TOBN(0xa9aba1f9, 0xfbe009df)}},
+ {{TOBN(0x857c1f22, 0x369b87ad), TOBN(0x3c00e5d9, 0x32fca556),
+ TOBN(0x1ad74cab, 0x90b06466), TOBN(0xa7112386, 0x550faaf2)},
+ {TOBN(0x7435e198, 0x6d9bd5f5), TOBN(0x2dcc7e38, 0x59c3463f),
+ TOBN(0xdc7df748, 0xca7bd4b2), TOBN(0x13cd4c08, 0x9dec2f31)}},
+ {{TOBN(0x0d3b5df8, 0xe3237710), TOBN(0x0dadb26e, 0xcbd2f7b0),
+ TOBN(0x9f5966ab, 0xe4aa082b), TOBN(0x666ec8de, 0x350e966e)},
+ {TOBN(0x1bfd1ed5, 0xee524216), TOBN(0xcd93c59b, 0x41dab0b6),
+ TOBN(0x658a8435, 0xd186d6ba), TOBN(0x1b7d34d2, 0x159d1195)}},
+ {{TOBN(0x5936e460, 0x22caf46b), TOBN(0x6a45dd8f, 0x9a96fe4f),
+ TOBN(0xf7925434, 0xb98f474e), TOBN(0x41410412, 0x0053ef15)},
+ {TOBN(0x71cf8d12, 0x41de97bf), TOBN(0xb8547b61, 0xbd80bef4),
+ TOBN(0xb47d3970, 0xc4db0037), TOBN(0xf1bcd328, 0xfef20dff)}},
+ {{TOBN(0x31a92e09, 0x10caad67), TOBN(0x1f591960, 0x5531a1e1),
+ TOBN(0x3bb852e0, 0x5f4fc840), TOBN(0x63e297ca, 0x93a72c6c)},
+ {TOBN(0x3c2b0b2e, 0x49abad67), TOBN(0x6ec405fc, 0xed3db0d9),
+ TOBN(0xdc14a530, 0x7fef1d40), TOBN(0xccd19846, 0x280896fc)}},
+ {{TOBN(0x00f83176, 0x9bb81648), TOBN(0xd69eb485, 0x653120d0),
+ TOBN(0xd17d75f4, 0x4ccabc62), TOBN(0x34a07f82, 0xb749fcb1)},
+ {TOBN(0x2c3af787, 0xbbfb5554), TOBN(0xb06ed4d0, 0x62e283f8),
+ TOBN(0x5722889f, 0xa19213a0), TOBN(0x162b085e, 0xdcf3c7b4)}},
+ {{TOBN(0xbcaecb31, 0xe0dd3eca), TOBN(0xc6237fbc, 0xe52f13a5),
+ TOBN(0xcc2b6b03, 0x27bac297), TOBN(0x2ae1cac5, 0xb917f54a)},
+ {TOBN(0x474807d4, 0x7845ae4f), TOBN(0xfec7dd92, 0xce5972e0),
+ TOBN(0xc3bd2541, 0x1d7915bb), TOBN(0x66f85dc4, 0xd94907ca)}},
+ {{TOBN(0xd981b888, 0xbdbcf0ca), TOBN(0xd75f5da6, 0xdf279e9f),
+ TOBN(0x128bbf24, 0x7054e934), TOBN(0x3c6ff6e5, 0x81db134b)},
+ {TOBN(0x795b7cf4, 0x047d26e4), TOBN(0xf370f7b8, 0x5049ec37),
+ TOBN(0xc6712d4d, 0xced945af), TOBN(0xdf30b5ec, 0x095642bc)}},
+ {{TOBN(0x9b034c62, 0x4896246e), TOBN(0x5652c016, 0xee90bbd1),
+ TOBN(0xeb38636f, 0x87fedb73), TOBN(0x5e32f847, 0x0135a613)},
+ {TOBN(0x0703b312, 0xcf933c83), TOBN(0xd05bb76e, 0x1a7f47e6),
+ TOBN(0x825e4f0c, 0x949c2415), TOBN(0x569e5622, 0x7250d6f8)}},
+ {{TOBN(0xbbe9eb3a, 0x6568013e), TOBN(0x8dbd203f, 0x22f243fc),
+ TOBN(0x9dbd7694, 0xb342734a), TOBN(0x8f6d12f8, 0x46afa984)},
+ {TOBN(0xb98610a2, 0xc9eade29), TOBN(0xbab4f323, 0x47dd0f18),
+ TOBN(0x5779737b, 0x671c0d46), TOBN(0x10b6a7c6, 0xd3e0a42a)}},
+ {{TOBN(0xfb19ddf3, 0x3035b41c), TOBN(0xd336343f, 0x99c45895),
+ TOBN(0x61fe4938, 0x54c857e5), TOBN(0xc4d506be, 0xae4e57d5)},
+ {TOBN(0x3cd8c8cb, 0xbbc33f75), TOBN(0x7281f08a, 0x9262c77d),
+ TOBN(0x083f4ea6, 0xf11a2823), TOBN(0x8895041e, 0x9fba2e33)}},
+ {{TOBN(0xfcdfea49, 0x9c438edf), TOBN(0x7678dcc3, 0x91edba44),
+ TOBN(0xf07b3b87, 0xe2ba50f0), TOBN(0xc13888ef, 0x43948c1b)},
+ {TOBN(0xc2135ad4, 0x1140af42), TOBN(0x8e5104f3, 0x926ed1a7),
+ TOBN(0xf24430cb, 0x88f6695f), TOBN(0x0ce0637b, 0x6d73c120)}},
+ {{TOBN(0xb2db01e6, 0xfe631e8f), TOBN(0x1c5563d7, 0xd7bdd24b),
+ TOBN(0x8daea3ba, 0x369ad44f), TOBN(0x000c81b6, 0x8187a9f9)},
+ {TOBN(0x5f48a951, 0xaae1fd9a), TOBN(0xe35626c7, 0x8d5aed8a),
+ TOBN(0x20952763, 0x0498c622), TOBN(0x76d17634, 0x773aa504)}},
+ {{TOBN(0x36d90dda, 0xeb300f7a), TOBN(0x9dcf7dfc, 0xedb5e801),
+ TOBN(0x645cb268, 0x74d5244c), TOBN(0xa127ee79, 0x348e3aa2)},
+ {TOBN(0x488acc53, 0x575f1dbb), TOBN(0x95037e85, 0x80e6161e),
+ TOBN(0x57e59283, 0x292650d0), TOBN(0xabe67d99, 0x14938216)}},
+ {{TOBN(0x3c7f944b, 0x3f8e1065), TOBN(0xed908cb6, 0x330e8924),
+ TOBN(0x08ee8fd5, 0x6f530136), TOBN(0x2227b7d5, 0xd7ffc169)},
+ {TOBN(0x4f55c893, 0xb5cd6dd5), TOBN(0x82225e11, 0xa62796e8),
+ TOBN(0x5c6cead1, 0xcb18e12c), TOBN(0x4381ae0c, 0x84f5a51a)}},
+ {{TOBN(0x345913d3, 0x7fafa4c8), TOBN(0x3d918082, 0x0491aac0),
+ TOBN(0x9347871f, 0x3e69264c), TOBN(0xbea9dd3c, 0xb4f4f0cd)},
+ {TOBN(0xbda5d067, 0x3eadd3e7), TOBN(0x0033c1b8, 0x0573bcd8),
+ TOBN(0x25589379, 0x5da2486c), TOBN(0xcb89ee5b, 0x86abbee7)}},
+ {{TOBN(0x8fe0a8f3, 0x22532e5d), TOBN(0xb6410ff0, 0x727dfc4c),
+ TOBN(0x619b9d58, 0x226726db), TOBN(0x5ec25669, 0x7a2b2dc7)},
+ {TOBN(0xaf4d2e06, 0x4c3beb01), TOBN(0x852123d0, 0x7acea556),
+ TOBN(0x0e9470fa, 0xf783487a), TOBN(0x75a7ea04, 0x5664b3eb)}},
+ {{TOBN(0x4ad78f35, 0x6798e4ba), TOBN(0x9214e6e5, 0xc7d0e091),
+ TOBN(0xc420b488, 0xb1290403), TOBN(0x64049e0a, 0xfc295749)},
+ {TOBN(0x03ef5af1, 0x3ae9841f), TOBN(0xdbe4ca19, 0xb0b662a6),
+ TOBN(0x46845c5f, 0xfa453458), TOBN(0xf8dabf19, 0x10b66722)}},
+ {{TOBN(0xb650f0aa, 0xcce2793b), TOBN(0x71db851e, 0xc5ec47c1),
+ TOBN(0x3eb78f3e, 0x3b234fa9), TOBN(0xb0c60f35, 0xfc0106ce)},
+ {TOBN(0x05427121, 0x774eadbd), TOBN(0x25367faf, 0xce323863),
+ TOBN(0x7541b5c9, 0xcd086976), TOBN(0x4ff069e2, 0xdc507ad1)}},
+ {{TOBN(0x74145256, 0x8776e667), TOBN(0x6e76142c, 0xb23c6bb5),
+ TOBN(0xdbf30712, 0x1b3a8a87), TOBN(0x60e7363e, 0x98450836)},
+ {TOBN(0x5741450e, 0xb7366d80), TOBN(0xe4ee14ca, 0x4837dbdf),
+ TOBN(0xa765eb9b, 0x69d4316f), TOBN(0x04548dca, 0x8ef43825)}},
+ {{TOBN(0x9c9f4e4c, 0x5ae888eb), TOBN(0x733abb51, 0x56e9ac99),
+ TOBN(0xdaad3c20, 0xba6ac029), TOBN(0x9b8dd3d3, 0x2ba3e38e)},
+ {TOBN(0xa9bb4c92, 0x0bc5d11a), TOBN(0xf20127a7, 0x9c5f88a3),
+ TOBN(0x4f52b06e, 0x161d3cb8), TOBN(0x26c1ff09, 0x6afaf0a6)}},
+ {{TOBN(0x32670d2f, 0x7189e71f), TOBN(0xc6438748, 0x5ecf91e7),
+ TOBN(0x15758e57, 0xdb757a21), TOBN(0x427d09f8, 0x290a9ce5)},
+ {TOBN(0x846a308f, 0x38384a7a), TOBN(0xaac3acb4, 0xb0732b99),
+ TOBN(0x9e941009, 0x17845819), TOBN(0x95cba111, 0xa7ce5e03)}},
+ {{TOBN(0x6f3d4f7f, 0xb00009c4), TOBN(0xb8396c27, 0x8ff28b5f),
+ TOBN(0xb1a9ae43, 0x1c97975d), TOBN(0x9d7ba8af, 0xe5d9fed5)},
+ {TOBN(0x338cf09f, 0x34f485b6), TOBN(0xbc0ddacc, 0x64122516),
+ TOBN(0xa450da12, 0x05d471fe), TOBN(0x4c3a6250, 0x628dd8c9)}},
+ {{TOBN(0x69c7d103, 0xd1295837), TOBN(0xa2893e50, 0x3807eb2f),
+ TOBN(0xd6e1e1de, 0xbdb41491), TOBN(0xc630745b, 0x5e138235)},
+ {TOBN(0xc892109e, 0x48661ae1), TOBN(0x8d17e7eb, 0xea2b2674),
+ TOBN(0x00ec0f87, 0xc328d6b5), TOBN(0x6d858645, 0xf079ff9e)}},
+ {{TOBN(0x6cdf243e, 0x19115ead), TOBN(0x1ce1393e, 0x4bac4fcf),
+ TOBN(0x2c960ed0, 0x9c29f25b), TOBN(0x59be4d8e, 0x9d388a05)},
+ {TOBN(0x0d46e06c, 0xd0def72b), TOBN(0xb923db5d, 0xe0342748),
+ TOBN(0xf7d3aacd, 0x936d4a3d), TOBN(0x558519cc, 0x0b0b099e)}},
+ {{TOBN(0x3ea8ebf8, 0x827097ef), TOBN(0x259353db, 0xd054f55d),
+ TOBN(0x84c89abc, 0x6d2ed089), TOBN(0x5c548b69, 0x8e096a7c)},
+ {TOBN(0xd587f616, 0x994b995d), TOBN(0x4d1531f6, 0xa5845601),
+ TOBN(0x792ab31e, 0x451fd9f0), TOBN(0xc8b57bb2, 0x65adf6ca)}},
+ {{TOBN(0x68440fcb, 0x1cd5ad73), TOBN(0xb9c860e6, 0x6144da4f),
+ TOBN(0x2ab286aa, 0x8462beb8), TOBN(0xcc6b8fff, 0xef46797f)},
+ {TOBN(0xac820da4, 0x20c8a471), TOBN(0x69ae05a1, 0x77ff7faf),
+ TOBN(0xb9163f39, 0xbfb5da77), TOBN(0xbd03e590, 0x2c73ab7a)}},
+ {{TOBN(0x7e862b5e, 0xb2940d9e), TOBN(0x3c663d86, 0x4b9af564),
+ TOBN(0xd8309031, 0xbde3033d), TOBN(0x298231b2, 0xd42c5bc6)},
+ {TOBN(0x42090d2c, 0x552ad093), TOBN(0xa4799d1c, 0xff854695),
+ TOBN(0x0a88b5d6, 0xd31f0d00), TOBN(0xf8b40825, 0xa2f26b46)}},
+ {{TOBN(0xec29b1ed, 0xf1bd7218), TOBN(0xd491c53b, 0x4b24c86e),
+ TOBN(0xd2fe588f, 0x3395ea65), TOBN(0x6f3764f7, 0x4456ef15)},
+ {TOBN(0xdb43116d, 0xcdc34800), TOBN(0xcdbcd456, 0xc1e33955),
+ TOBN(0xefdb5540, 0x74ab286b), TOBN(0x948c7a51, 0xd18c5d7c)}},
+ {{TOBN(0xeb81aa37, 0x7378058e), TOBN(0x41c746a1, 0x04411154),
+ TOBN(0xa10c73bc, 0xfb828ac7), TOBN(0x6439be91, 0x9d972b29)},
+ {TOBN(0x4bf3b4b0, 0x43a2fbad), TOBN(0x39e6dadf, 0x82b5e840),
+ TOBN(0x4f716408, 0x6397bd4c), TOBN(0x0f7de568, 0x7f1eeccb)}},
+ {{TOBN(0x5865c5a1, 0xd2ffbfc1), TOBN(0xf74211fa, 0x4ccb6451),
+ TOBN(0x66368a88, 0xc0b32558), TOBN(0x5b539dc2, 0x9ad7812e)},
+ {TOBN(0x579483d0, 0x2f3af6f6), TOBN(0x52132078, 0x99934ece),
+ TOBN(0x50b9650f, 0xdcc9e983), TOBN(0xca989ec9, 0xaee42b8a)}},
+ {{TOBN(0x6a44c829, 0xd6f62f99), TOBN(0x8f06a309, 0x4c2a7c0c),
+ TOBN(0x4ea2b3a0, 0x98a0cb0a), TOBN(0x5c547b70, 0xbeee8364)},
+ {TOBN(0x461d40e1, 0x682afe11), TOBN(0x9e0fc77a, 0x7b41c0a8),
+ TOBN(0x79e4aefd, 0xe20d5d36), TOBN(0x2916e520, 0x32dd9f63)}},
+ {{TOBN(0xf59e52e8, 0x3f883faf), TOBN(0x396f9639, 0x2b868d35),
+ TOBN(0xc902a9df, 0x4ca19881), TOBN(0x0fc96822, 0xdb2401a6)},
+ {TOBN(0x41237587, 0x66f1c68d), TOBN(0x10fc6de3, 0xfb476c0d),
+ TOBN(0xf8b6b579, 0x841f5d90), TOBN(0x2ba8446c, 0xfa24f44a)}},
+ {{TOBN(0xa237b920, 0xef4a9975), TOBN(0x60bb6004, 0x2330435f),
+ TOBN(0xd6f4ab5a, 0xcfb7e7b5), TOBN(0xb2ac5097, 0x83435391)},
+ {TOBN(0xf036ee2f, 0xb0d1ea67), TOBN(0xae779a6a, 0x74c56230),
+ TOBN(0x59bff8c8, 0xab838ae6), TOBN(0xcd83ca99, 0x9b38e6f0)}},
+ {{TOBN(0xbb27bef5, 0xe33deed3), TOBN(0xe6356f6f, 0x001892a8),
+ TOBN(0xbf3be6cc, 0x7adfbd3e), TOBN(0xaecbc81c, 0x33d1ac9d)},
+ {TOBN(0xe4feb909, 0xe6e861dc), TOBN(0x90a247a4, 0x53f5f801),
+ TOBN(0x01c50acb, 0x27346e57), TOBN(0xce29242e, 0x461acc1b)}},
+ {{TOBN(0x04dd214a, 0x2f998a91), TOBN(0x271ee9b1, 0xd4baf27b),
+ TOBN(0x7e3027d1, 0xe8c26722), TOBN(0x21d1645c, 0x1820dce5)},
+ {TOBN(0x086f242c, 0x7501779c), TOBN(0xf0061407, 0xfa0e8009),
+ TOBN(0xf23ce477, 0x60187129), TOBN(0x05bbdedb, 0x0fde9bd0)}},
+ {{TOBN(0x682f4832, 0x25d98473), TOBN(0xf207fe85, 0x5c658427),
+ TOBN(0xb6fdd7ba, 0x4166ffa1), TOBN(0x0c314056, 0x9eed799d)},
+ {TOBN(0x0db8048f, 0x4107e28f), TOBN(0x74ed3871, 0x41216840),
+ TOBN(0x74489f8f, 0x56a3c06e), TOBN(0x1e1c005b, 0x12777134)}},
+ {{TOBN(0xdb332a73, 0xf37ec3c3), TOBN(0xc65259bd, 0xdd59eba0),
+ TOBN(0x2291709c, 0xdb4d3257), TOBN(0x9a793b25, 0xbd389390)},
+ {TOBN(0xf39fe34b, 0xe43756f0), TOBN(0x2f76bdce, 0x9afb56c9),
+ TOBN(0x9f37867a, 0x61208b27), TOBN(0xea1d4307, 0x089972c3)}},
+ {{TOBN(0x8c595330, 0x8bdf623a), TOBN(0x5f5accda, 0x8441fb7d),
+ TOBN(0xfafa9418, 0x32ddfd95), TOBN(0x6ad40c5a, 0x0fde9be7)},
+ {TOBN(0x43faba89, 0xaeca8709), TOBN(0xc64a7cf1, 0x2c248a9d),
+ TOBN(0x16620252, 0x72637a76), TOBN(0xaee1c791, 0x22b8d1bb)}},
+ {{TOBN(0xf0f798fd, 0x21a843b2), TOBN(0x56e4ed4d, 0x8d005cb1),
+ TOBN(0x355f7780, 0x1f0d8abe), TOBN(0x197b04cf, 0x34522326)},
+ {TOBN(0x41f9b31f, 0xfd42c13f), TOBN(0x5ef7feb2, 0xb40f933d),
+ TOBN(0x27326f42, 0x5d60bad4), TOBN(0x027ecdb2, 0x8c92cf89)}},
+ {{TOBN(0x04aae4d1, 0x4e3352fe), TOBN(0x08414d2f, 0x73591b90),
+ TOBN(0x5ed6124e, 0xb7da7d60), TOBN(0xb985b931, 0x4d13d4ec)},
+ {TOBN(0xa592d3ab, 0x96bf36f9), TOBN(0x012dbed5, 0xbbdf51df),
+ TOBN(0xa57963c0, 0xdf6c177d), TOBN(0x010ec869, 0x87ca29cf)}},
+ {{TOBN(0xba1700f6, 0xbf926dff), TOBN(0x7c9fdbd1, 0xf4bf6bc2),
+ TOBN(0xdc18dc8f, 0x64da11f5), TOBN(0xa6074b7a, 0xd938ae75)},
+ {TOBN(0x14270066, 0xe84f44a4), TOBN(0x99998d38, 0xd27b954e),
+ TOBN(0xc1be8ab2, 0xb4f38e9a), TOBN(0x8bb55bbf, 0x15c01016)}},
+ {{TOBN(0xf73472b4, 0x0ea2ab30), TOBN(0xd365a340, 0xf73d68dd),
+ TOBN(0xc01a7168, 0x19c2e1eb), TOBN(0x32f49e37, 0x34061719)},
+ {TOBN(0xb73c57f1, 0x01d8b4d6), TOBN(0x03c8423c, 0x26b47700),
+ TOBN(0x321d0bc8, 0xa4d8826a), TOBN(0x6004213c, 0x4bc0e638)}},
+ {{TOBN(0xf78c64a1, 0xc1c06681), TOBN(0x16e0a16f, 0xef018e50),
+ TOBN(0x31cbdf91, 0xdb42b2b3), TOBN(0xf8f4ffce, 0xe0d36f58)},
+ {TOBN(0xcdcc71cd, 0x4cc5e3e0), TOBN(0xd55c7cfa, 0xa129e3e0),
+ TOBN(0xccdb6ba0, 0x0fb2cbf1), TOBN(0x6aba0005, 0xc4bce3cb)}},
+ {{TOBN(0x501cdb30, 0xd232cfc4), TOBN(0x9ddcf12e, 0xd58a3cef),
+ TOBN(0x02d2cf9c, 0x87e09149), TOBN(0xdc5d7ec7, 0x2c976257)},
+ {TOBN(0x6447986e, 0x0b50d7dd), TOBN(0x88fdbaf7, 0x807f112a),
+ TOBN(0x58c9822a, 0xb00ae9f6), TOBN(0x6abfb950, 0x6d3d27e0)}},
+ {{TOBN(0xd0a74487, 0x8a429f4f), TOBN(0x0649712b, 0xdb516609),
+ TOBN(0xb826ba57, 0xe769b5df), TOBN(0x82335df2, 0x1fc7aaf2)},
+ {TOBN(0x2389f067, 0x5c93d995), TOBN(0x59ac367a, 0x68677be6),
+ TOBN(0xa77985ff, 0x21d9951b), TOBN(0x038956fb, 0x85011cce)}},
+ {{TOBN(0x608e48cb, 0xbb734e37), TOBN(0xc08c0bf2, 0x2be5b26f),
+ TOBN(0x17bbdd3b, 0xf9b1a0d9), TOBN(0xeac7d898, 0x10483319)},
+ {TOBN(0xc95c4baf, 0xbc1a6dea), TOBN(0xfdd0e2bf, 0x172aafdb),
+ TOBN(0x40373cbc, 0x8235c41a), TOBN(0x14303f21, 0xfb6f41d5)}},
+ {{TOBN(0xba063621, 0x0408f237), TOBN(0xcad3b09a, 0xecd2d1ed),
+ TOBN(0x4667855a, 0x52abb6a2), TOBN(0xba9157dc, 0xaa8b417b)},
+ {TOBN(0xfe7f3507, 0x4f013efb), TOBN(0x1b112c4b, 0xaa38c4a2),
+ TOBN(0xa1406a60, 0x9ba64345), TOBN(0xe53cba33, 0x6993c80b)}},
+ {{TOBN(0x45466063, 0xded40d23), TOBN(0x3d5f1f4d, 0x54908e25),
+ TOBN(0x9ebefe62, 0x403c3c31), TOBN(0x274ea0b5, 0x0672a624)},
+ {TOBN(0xff818d99, 0x451d1b71), TOBN(0x80e82643, 0x8f79cf79),
+ TOBN(0xa165df13, 0x73ce37f5), TOBN(0xa744ef4f, 0xfe3a21fd)}},
+ {{TOBN(0x73f1e7f5, 0xcf551396), TOBN(0xc616898e, 0x868c676b),
+ TOBN(0x671c28c7, 0x8c442c36), TOBN(0xcfe5e558, 0x5e0a317d)},
+ {TOBN(0x1242d818, 0x7051f476), TOBN(0x56fad2a6, 0x14f03442),
+ TOBN(0x262068bc, 0x0a44d0f6), TOBN(0xdfa2cd6e, 0xce6edf4e)}},
+ {{TOBN(0x0f43813a, 0xd15d1517), TOBN(0x61214cb2, 0x377d44f5),
+ TOBN(0xd399aa29, 0xc639b35f), TOBN(0x42136d71, 0x54c51c19)},
+ {TOBN(0x9774711b, 0x08417221), TOBN(0x0a5546b3, 0x52545a57),
+ TOBN(0x80624c41, 0x1150582d), TOBN(0x9ec5c418, 0xfbc555bc)}},
+ {{TOBN(0x2c87dcad, 0x771849f1), TOBN(0xb0c932c5, 0x01d7bf6f),
+ TOBN(0x6aa5cd3e, 0x89116eb2), TOBN(0xd378c25a, 0x51ca7bd3)},
+ {TOBN(0xc612a0da, 0x9e6e3e31), TOBN(0x0417a54d, 0xb68ad5d0),
+ TOBN(0x00451e4a, 0x22c6edb8), TOBN(0x9fbfe019, 0xb42827ce)}},
+ {{TOBN(0x2fa92505, 0xba9384a2), TOBN(0x21b8596e, 0x64ad69c1),
+ TOBN(0x8f4fcc49, 0x983b35a6), TOBN(0xde093760, 0x72754672)},
+ {TOBN(0x2f14ccc8, 0xf7bffe6d), TOBN(0x27566bff, 0x5d94263d),
+ TOBN(0xb5b4e9c6, 0x2df3ec30), TOBN(0x94f1d7d5, 0x3e6ea6ba)}},
+ {{TOBN(0x97b7851a, 0xaaca5e9b), TOBN(0x518aa521, 0x56713b97),
+ TOBN(0x3357e8c7, 0x150a61f6), TOBN(0x7842e7e2, 0xec2c2b69)},
+ {TOBN(0x8dffaf65, 0x6868a548), TOBN(0xd963bd82, 0xe068fc81),
+ TOBN(0x64da5c8b, 0x65917733), TOBN(0x927090ff, 0x7b247328)}}},
+ {{{TOBN(0x214bc9a7, 0xd298c241), TOBN(0xe3b697ba, 0x56807cfd),
+ TOBN(0xef1c7802, 0x4564eadb), TOBN(0xdde8cdcf, 0xb48149c5)},
+ {TOBN(0x946bf0a7, 0x5a4d2604), TOBN(0x27154d7f, 0x6c1538af),
+ TOBN(0x95cc9230, 0xde5b1fcc), TOBN(0xd88519e9, 0x66864f82)}},
+ {{TOBN(0xb828dd1a, 0x7cb1282c), TOBN(0xa08d7626, 0xbe46973a),
+ TOBN(0x6baf8d40, 0xe708d6b2), TOBN(0x72571fa1, 0x4daeb3f3)},
+ {TOBN(0x85b1732f, 0xf22dfd98), TOBN(0x87ab01a7, 0x0087108d),
+ TOBN(0xaaaafea8, 0x5988207a), TOBN(0xccc832f8, 0x69f00755)}},
+ {{TOBN(0x964d950e, 0x36ff3bf0), TOBN(0x8ad20f6f, 0xf0b34638),
+ TOBN(0x4d9177b3, 0xb5d7585f), TOBN(0xcf839760, 0xef3f019f)},
+ {TOBN(0x582fc5b3, 0x8288c545), TOBN(0x2f8e4e9b, 0x13116bd1),
+ TOBN(0xf91e1b2f, 0x332120ef), TOBN(0xcf568724, 0x2a17dd23)}},
+ {{TOBN(0x488f1185, 0xca8d9d1a), TOBN(0xadf2c77d, 0xd987ded2),
+ TOBN(0x5f3039f0, 0x60c46124), TOBN(0xe5d70b75, 0x71e095f4)},
+ {TOBN(0x82d58650, 0x6260e70f), TOBN(0x39d75ea7, 0xf750d105),
+ TOBN(0x8cf3d0b1, 0x75bac364), TOBN(0xf3a7564d, 0x21d01329)}},
+ {{TOBN(0x182f04cd, 0x2f52d2a7), TOBN(0x4fde149a, 0xe2df565a),
+ TOBN(0xb80c5eec, 0xa79fb2f7), TOBN(0xab491d7b, 0x22ddc897)},
+ {TOBN(0x99d76c18, 0xc6312c7f), TOBN(0xca0d5f3d, 0x6aa41a57),
+ TOBN(0x71207325, 0xd15363a0), TOBN(0xe82aa265, 0xbeb252c2)}},
+ {{TOBN(0x94ab4700, 0xec3128c2), TOBN(0x6c76d862, 0x8e383f49),
+ TOBN(0xdc36b150, 0xc03024eb), TOBN(0xfb439477, 0x53daac69)},
+ {TOBN(0xfc68764a, 0x8dc79623), TOBN(0x5b86995d, 0xb440fbb2),
+ TOBN(0xd66879bf, 0xccc5ee0d), TOBN(0x05228942, 0x95aa8bd3)}},
+ {{TOBN(0xb51a40a5, 0x1e6a75c1), TOBN(0x24327c76, 0x0ea7d817),
+ TOBN(0x06630182, 0x07774597), TOBN(0xd6fdbec3, 0x97fa7164)},
+ {TOBN(0x20c99dfb, 0x13c90f48), TOBN(0xd6ac5273, 0x686ef263),
+ TOBN(0xc6a50bdc, 0xfef64eeb), TOBN(0xcd87b281, 0x86fdfc32)}},
+ {{TOBN(0xb24aa43e, 0x3fcd3efc), TOBN(0xdd26c034, 0xb8088e9a),
+ TOBN(0xa5ef4dc9, 0xbd3d46ea), TOBN(0xa2f99d58, 0x8a4c6a6f)},
+ {TOBN(0xddabd355, 0x2f1da46c), TOBN(0x72c3f8ce, 0x1afacdd1),
+ TOBN(0xd90c4eee, 0x92d40578), TOBN(0xd28bb41f, 0xca623b94)}},
+ {{TOBN(0x50fc0711, 0x745edc11), TOBN(0x9dd9ad7d, 0x3dc87558),
+ TOBN(0xce6931fb, 0xb49d1e64), TOBN(0x6c77a0a2, 0xc98bd0f9)},
+ {TOBN(0x62b9a629, 0x6baf7cb1), TOBN(0xcf065f91, 0xccf72d22),
+ TOBN(0x7203cce9, 0x79639071), TOBN(0x09ae4885, 0xf9cb732f)}},
+ {{TOBN(0x5e7c3bec, 0xee8314f3), TOBN(0x1c068aed, 0xdbea298f),
+ TOBN(0x08d381f1, 0x7c80acec), TOBN(0x03b56be8, 0xe330495b)},
+ {TOBN(0xaeffb8f2, 0x9222882d), TOBN(0x95ff38f6, 0xc4af8bf7),
+ TOBN(0x50e32d35, 0x1fc57d8c), TOBN(0x6635be52, 0x17b444f0)}},
+ {{TOBN(0x04d15276, 0xa5177900), TOBN(0x4e1dbb47, 0xf6858752),
+ TOBN(0x5b475622, 0xc615796c), TOBN(0xa6fa0387, 0x691867bf)},
+ {TOBN(0xed7f5d56, 0x2844c6d0), TOBN(0xc633cf9b, 0x03a2477d),
+ TOBN(0xf6be5c40, 0x2d3721d6), TOBN(0xaf312eb7, 0xe9fd68e6)}},
+ {{TOBN(0x242792d2, 0xe7417ce1), TOBN(0xff42bc71, 0x970ee7f5),
+ TOBN(0x1ff4dc6d, 0x5c67a41e), TOBN(0x77709b7b, 0x20882a58)},
+ {TOBN(0x3554731d, 0xbe217f2c), TOBN(0x2af2a8cd, 0x5bb72177),
+ TOBN(0x58eee769, 0x591dd059), TOBN(0xbb2930c9, 0x4bba6477)}},
+ {{TOBN(0x863ee047, 0x7d930cfc), TOBN(0x4c262ad1, 0x396fd1f4),
+ TOBN(0xf4765bc8, 0x039af7e1), TOBN(0x2519834b, 0x5ba104f6)},
+ {TOBN(0x7cd61b4c, 0xd105f961), TOBN(0xa5415da5, 0xd63bca54),
+ TOBN(0x778280a0, 0x88a1f17c), TOBN(0xc4968949, 0x2329512c)}},
+ {{TOBN(0x174a9126, 0xcecdaa7a), TOBN(0xfc8c7e0e, 0x0b13247b),
+ TOBN(0x29c110d2, 0x3484c1c4), TOBN(0xf8eb8757, 0x831dfc3b)},
+ {TOBN(0x022f0212, 0xc0067452), TOBN(0x3f6f69ee, 0x7b9b926c),
+ TOBN(0x09032da0, 0xef42daf4), TOBN(0x79f00ade, 0x83f80de4)}},
+ {{TOBN(0x6210db71, 0x81236c97), TOBN(0x74f7685b, 0x3ee0781f),
+ TOBN(0x4df7da7b, 0xa3e41372), TOBN(0x2aae38b1, 0xb1a1553e)},
+ {TOBN(0x1688e222, 0xf6dd9d1b), TOBN(0x57695448, 0x5b8b6487),
+ TOBN(0x478d2127, 0x4b2edeaa), TOBN(0xb2818fa5, 0x1e85956a)}},
+ {{TOBN(0x1e6addda, 0xf176f2c0), TOBN(0x01ca4604, 0xe2572658),
+ TOBN(0x0a404ded, 0x85342ffb), TOBN(0x8cf60f96, 0x441838d6)},
+ {TOBN(0x9bbc691c, 0xc9071c4a), TOBN(0xfd588744, 0x34442803),
+ TOBN(0x97101c85, 0x809c0d81), TOBN(0xa7fb754c, 0x8c456f7f)}},
+ {{TOBN(0xc95f3c5c, 0xd51805e1), TOBN(0xab4ccd39, 0xb299dca8),
+ TOBN(0x3e03d20b, 0x47eaf500), TOBN(0xfa3165c1, 0xd7b80893)},
+ {TOBN(0x005e8b54, 0xe160e552), TOBN(0xdc4972ba, 0x9019d11f),
+ TOBN(0x21a6972e, 0x0c9a4a7a), TOBN(0xa52c258f, 0x37840fd7)}},
+ {{TOBN(0xf8559ff4, 0xc1e99d81), TOBN(0x08e1a7d6, 0xa3c617c0),
+ TOBN(0xb398fd43, 0x248c6ba7), TOBN(0x6ffedd91, 0xd1283794)},
+ {TOBN(0x8a6a59d2, 0xd629d208), TOBN(0xa9d141d5, 0x3490530e),
+ TOBN(0x42f6fc18, 0x38505989), TOBN(0x09bf250d, 0x479d94ee)}},
+ {{TOBN(0x223ad3b1, 0xb3822790), TOBN(0x6c5926c0, 0x93b8971c),
+ TOBN(0x609efc7e, 0x75f7fa62), TOBN(0x45d66a6d, 0x1ec2d989)},
+ {TOBN(0x4422d663, 0x987d2792), TOBN(0x4a73caad, 0x3eb31d2b),
+ TOBN(0xf06c2ac1, 0xa32cb9e6), TOBN(0xd9445c5f, 0x91aeba84)}},
+ {{TOBN(0x6af7a1d5, 0xaf71013f), TOBN(0xe68216e5, 0x0bedc946),
+ TOBN(0xf4cba30b, 0xd27370a0), TOBN(0x7981afbf, 0x870421cc)},
+ {TOBN(0x02496a67, 0x9449f0e1), TOBN(0x86cfc4be, 0x0a47edae),
+ TOBN(0x3073c936, 0xb1feca22), TOBN(0xf5694612, 0x03f8f8fb)}},
+ {{TOBN(0xd063b723, 0x901515ea), TOBN(0x4c6c77a5, 0x749cf038),
+ TOBN(0x6361e360, 0xab9e5059), TOBN(0x596cf171, 0xa76a37c0)},
+ {TOBN(0x800f53fa, 0x6530ae7a), TOBN(0x0f5e631e, 0x0792a7a6),
+ TOBN(0x5cc29c24, 0xefdb81c9), TOBN(0xa269e868, 0x3f9c40ba)}},
+ {{TOBN(0xec14f9e1, 0x2cb7191e), TOBN(0x78ea1bd8, 0xe5b08ea6),
+ TOBN(0x3c65aa9b, 0x46332bb9), TOBN(0x84cc22b3, 0xbf80ce25)},
+ {TOBN(0x0098e9e9, 0xd49d5bf1), TOBN(0xcd4ec1c6, 0x19087da4),
+ TOBN(0x3c9d07c5, 0xaef6e357), TOBN(0x839a0268, 0x9f8f64b8)}},
+ {{TOBN(0xc5e9eb62, 0xc6d8607f), TOBN(0x759689f5, 0x6aa995e4),
+ TOBN(0x70464669, 0xbbb48317), TOBN(0x921474bf, 0xe402417d)},
+ {TOBN(0xcabe135b, 0x2a354c8c), TOBN(0xd51e52d2, 0x812fa4b5),
+ TOBN(0xec741096, 0x53311fe8), TOBN(0x4f774535, 0xb864514b)}},
+ {{TOBN(0xbcadd671, 0x5bde48f8), TOBN(0xc9703873, 0x2189bc7d),
+ TOBN(0x5d45299e, 0xc709ee8a), TOBN(0xd1287ee2, 0x845aaff8)},
+ {TOBN(0x7d1f8874, 0xdb1dbf1f), TOBN(0xea46588b, 0x990c88d6),
+ TOBN(0x60ba649a, 0x84368313), TOBN(0xd5fdcbce, 0x60d543ae)}},
+ {{TOBN(0x90b46d43, 0x810d5ab0), TOBN(0x6739d8f9, 0x04d7e5cc),
+ TOBN(0x021c1a58, 0x0d337c33), TOBN(0x00a61162, 0x68e67c40)},
+ {TOBN(0x95ef413b, 0x379f0a1f), TOBN(0xfe126605, 0xe9e2ab95),
+ TOBN(0x67578b85, 0x2f5f199c), TOBN(0xf5c00329, 0x2cb84913)}},
+ {{TOBN(0xf7956430, 0x37577dd8), TOBN(0x83b82af4, 0x29c5fe88),
+ TOBN(0x9c1bea26, 0xcdbdc132), TOBN(0x589fa086, 0x9c04339e)},
+ {TOBN(0x033e9538, 0xb13799df), TOBN(0x85fa8b21, 0xd295d034),
+ TOBN(0xdf17f73f, 0xbd9ddcca), TOBN(0xf32bd122, 0xddb66334)}},
+ {{TOBN(0x55ef88a7, 0x858b044c), TOBN(0x1f0d69c2, 0x5aa9e397),
+ TOBN(0x55fd9cc3, 0x40d85559), TOBN(0xc774df72, 0x7785ddb2)},
+ {TOBN(0x5dcce9f6, 0xd3bd2e1c), TOBN(0xeb30da20, 0xa85dfed0),
+ TOBN(0x5ed7f5bb, 0xd3ed09c4), TOBN(0x7d42a35c, 0x82a9c1bd)}},
+ {{TOBN(0xcf3de995, 0x9890272d), TOBN(0x75f3432a, 0x3e713a10),
+ TOBN(0x5e13479f, 0xe28227b8), TOBN(0xb8561ea9, 0xfefacdc8)},
+ {TOBN(0xa6a297a0, 0x8332aafd), TOBN(0x9b0d8bb5, 0x73809b62),
+ TOBN(0xd2fa1cfd, 0x0c63036f), TOBN(0x7a16eb55, 0xbd64bda8)}},
+ {{TOBN(0x3f5cf5f6, 0x78e62ddc), TOBN(0x2267c454, 0x07fd752b),
+ TOBN(0x5e361b6b, 0x5e437bbe), TOBN(0x95c59501, 0x8354e075)},
+ {TOBN(0xec725f85, 0xf2b254d9), TOBN(0x844b617d, 0x2cb52b4e),
+ TOBN(0xed8554f5, 0xcf425fb5), TOBN(0xab67703e, 0x2af9f312)}},
+ {{TOBN(0x4cc34ec1, 0x3cf48283), TOBN(0xb09daa25, 0x9c8a705e),
+ TOBN(0xd1e9d0d0, 0x5b7d4f84), TOBN(0x4df6ef64, 0xdb38929d)},
+ {TOBN(0xe16b0763, 0xaa21ba46), TOBN(0xc6b1d178, 0xa293f8fb),
+ TOBN(0x0ff5b602, 0xd520aabf), TOBN(0x94d671bd, 0xc339397a)}},
+ {{TOBN(0x7c7d98cf, 0x4f5792fa), TOBN(0x7c5e0d67, 0x11215261),
+ TOBN(0x9b19a631, 0xa7c5a6d4), TOBN(0xc8511a62, 0x7a45274d)},
+ {TOBN(0x0c16621c, 0xa5a60d99), TOBN(0xf7fbab88, 0xcf5e48cb),
+ TOBN(0xab1e6ca2, 0xf7ddee08), TOBN(0x83bd08ce, 0xe7867f3c)}},
+ {{TOBN(0xf7e48e8a, 0x2ac13e27), TOBN(0x4494f6df, 0x4eb1a9f5),
+ TOBN(0xedbf84eb, 0x981f0a62), TOBN(0x49badc32, 0x536438f0)},
+ {TOBN(0x50bea541, 0x004f7571), TOBN(0xbac67d10, 0xdf1c94ee),
+ TOBN(0x253d73a1, 0xb727bc31), TOBN(0xb3d01cf2, 0x30686e28)}},
+ {{TOBN(0x51b77b1b, 0x55fd0b8b), TOBN(0xa099d183, 0xfeec3173),
+ TOBN(0x202b1fb7, 0x670e72b7), TOBN(0xadc88b33, 0xa8e1635f)},
+ {TOBN(0x34e8216a, 0xf989d905), TOBN(0xc2e68d20, 0x29b58d01),
+ TOBN(0x11f81c92, 0x6fe55a93), TOBN(0x15f1462a, 0x8f296f40)}},
+ {{TOBN(0x1915d375, 0xea3d62f2), TOBN(0xa17765a3, 0x01c8977d),
+ TOBN(0x7559710a, 0xe47b26f6), TOBN(0xe0bd29c8, 0x535077a5)},
+ {TOBN(0x615f976d, 0x08d84858), TOBN(0x370dfe85, 0x69ced5c1),
+ TOBN(0xbbc7503c, 0xa734fa56), TOBN(0xfbb9f1ec, 0x91ac4574)}},
+ {{TOBN(0x95d7ec53, 0x060dd7ef), TOBN(0xeef2dacd, 0x6e657979),
+ TOBN(0x54511af3, 0xe2a08235), TOBN(0x1e324aa4, 0x1f4aea3d)},
+ {TOBN(0x550e7e71, 0xe6e67671), TOBN(0xbccd5190, 0xbf52faf7),
+ TOBN(0xf880d316, 0x223cc62a), TOBN(0x0d402c7e, 0x2b32eb5d)}},
+ {{TOBN(0xa40bc039, 0x306a5a3b), TOBN(0x4e0a41fd, 0x96783a1b),
+ TOBN(0xa1e8d39a, 0x0253cdd4), TOBN(0x6480be26, 0xc7388638)},
+ {TOBN(0xee365e1d, 0x2285f382), TOBN(0x188d8d8f, 0xec0b5c36),
+ TOBN(0x34ef1a48, 0x1f0f4d82), TOBN(0x1a8f43e1, 0xa487d29a)}},
+ {{TOBN(0x8168226d, 0x77aefb3a), TOBN(0xf69a751e, 0x1e72c253),
+ TOBN(0x8e04359a, 0xe9594df1), TOBN(0x475ffd7d, 0xd14c0467)},
+ {TOBN(0xb5a2c2b1, 0x3844e95c), TOBN(0x85caf647, 0xdd12ef94),
+ TOBN(0x1ecd2a9f, 0xf1063d00), TOBN(0x1dd2e229, 0x23843311)}},
+ {{TOBN(0x38f0e09d, 0x73d17244), TOBN(0x3ede7746, 0x8fc653f1),
+ TOBN(0xae4459f5, 0xdc20e21c), TOBN(0x00db2ffa, 0x6a8599ea)},
+ {TOBN(0x11682c39, 0x30cfd905), TOBN(0x4934d074, 0xa5c112a6),
+ TOBN(0xbdf063c5, 0x568bfe95), TOBN(0x779a440a, 0x016c441a)}},
+ {{TOBN(0x0c23f218, 0x97d6fbdc), TOBN(0xd3a5cd87, 0xe0776aac),
+ TOBN(0xcee37f72, 0xd712e8db), TOBN(0xfb28c70d, 0x26f74e8d)},
+ {TOBN(0xffe0c728, 0xb61301a0), TOBN(0xa6282168, 0xd3724354),
+ TOBN(0x7ff4cb00, 0x768ffedc), TOBN(0xc51b3088, 0x03b02de9)}},
+ {{TOBN(0xa5a8147c, 0x3902dda5), TOBN(0x35d2f706, 0xfe6973b4),
+ TOBN(0x5ac2efcf, 0xc257457e), TOBN(0x933f48d4, 0x8700611b)},
+ {TOBN(0xc365af88, 0x4912beb2), TOBN(0x7f5a4de6, 0x162edf94),
+ TOBN(0xc646ba7c, 0x0c32f34b), TOBN(0x632c6af3, 0xb2091074)}},
+ {{TOBN(0x58d4f2e3, 0x753e43a9), TOBN(0x70e1d217, 0x24d4e23f),
+ TOBN(0xb24bf729, 0xafede6a6), TOBN(0x7f4a94d8, 0x710c8b60)},
+ {TOBN(0xaad90a96, 0x8d4faa6a), TOBN(0xd9ed0b32, 0xb066b690),
+ TOBN(0x52fcd37b, 0x78b6dbfd), TOBN(0x0b64615e, 0x8bd2b431)}},
+ {{TOBN(0x228e2048, 0xcfb9fad5), TOBN(0xbeaa386d, 0x240b76bd),
+ TOBN(0x2d6681c8, 0x90dad7bc), TOBN(0x3e553fc3, 0x06d38f5e)},
+ {TOBN(0xf27cdb9b, 0x9d5f9750), TOBN(0x3e85c52a, 0xd28c5b0e),
+ TOBN(0x190795af, 0x5247c39b), TOBN(0x547831eb, 0xbddd6828)}},
+ {{TOBN(0xf327a227, 0x4a82f424), TOBN(0x36919c78, 0x7e47f89d),
+ TOBN(0xe4783919, 0x43c7392c), TOBN(0xf101b9aa, 0x2316fefe)},
+ {TOBN(0xbcdc9e9c, 0x1c5009d2), TOBN(0xfb55ea13, 0x9cd18345),
+ TOBN(0xf5b5e231, 0xa3ce77c7), TOBN(0xde6b4527, 0xd2f2cb3d)}},
+ {{TOBN(0x10f6a333, 0x9bb26f5f), TOBN(0x1e85db8e, 0x044d85b6),
+ TOBN(0xc3697a08, 0x94197e54), TOBN(0x65e18cc0, 0xa7cb4ea8)},
+ {TOBN(0xa38c4f50, 0xa471fe6e), TOBN(0xf031747a, 0x2f13439c),
+ TOBN(0x53c4a6ba, 0xc007318b), TOBN(0xa8da3ee5, 0x1deccb3d)}},
+ {{TOBN(0x0555b31c, 0x558216b1), TOBN(0x90c7810c, 0x2f79e6c2),
+ TOBN(0x9b669f4d, 0xfe8eed3c), TOBN(0x70398ec8, 0xe0fac126)},
+ {TOBN(0xa96a449e, 0xf701b235), TOBN(0x0ceecdb3, 0xeb94f395),
+ TOBN(0x285fc368, 0xd0cb7431), TOBN(0x0d37bb52, 0x16a18c64)}},
+ {{TOBN(0x05110d38, 0xb880d2dd), TOBN(0xa60f177b, 0x65930d57),
+ TOBN(0x7da34a67, 0xf36235f5), TOBN(0x47f5e17c, 0x183816b9)},
+ {TOBN(0xc7664b57, 0xdb394af4), TOBN(0x39ba215d, 0x7036f789),
+ TOBN(0x46d2ca0e, 0x2f27b472), TOBN(0xc42647ee, 0xf73a84b7)}},
+ {{TOBN(0x44bc7545, 0x64488f1d), TOBN(0xaa922708, 0xf4cf85d5),
+ TOBN(0x721a01d5, 0x53e4df63), TOBN(0x649c0c51, 0x5db46ced)},
+ {TOBN(0x6bf0d64e, 0x3cffcb6c), TOBN(0xe3bf93fe, 0x50f71d96),
+ TOBN(0x75044558, 0xbcc194a0), TOBN(0x16ae3372, 0x6afdc554)}},
+ {{TOBN(0xbfc01adf, 0x5ca48f3f), TOBN(0x64352f06, 0xe22a9b84),
+ TOBN(0xcee54da1, 0xc1099e4a), TOBN(0xbbda54e8, 0xfa1b89c0)},
+ {TOBN(0x166a3df5, 0x6f6e55fb), TOBN(0x1ca44a24, 0x20176f88),
+ TOBN(0x936afd88, 0xdfb7b5ff), TOBN(0xe34c2437, 0x8611d4a0)}},
+ {{TOBN(0x7effbb75, 0x86142103), TOBN(0x6704ba1b, 0x1f34fc4d),
+ TOBN(0x7c2a468f, 0x10c1b122), TOBN(0x36b3a610, 0x8c6aace9)},
+ {TOBN(0xabfcc0a7, 0x75a0d050), TOBN(0x066f9197, 0x3ce33e32),
+ TOBN(0xce905ef4, 0x29fe09be), TOBN(0x89ee25ba, 0xa8376351)}},
+ {{TOBN(0x2a3ede22, 0xfd29dc76), TOBN(0x7fd32ed9, 0x36f17260),
+ TOBN(0x0cadcf68, 0x284b4126), TOBN(0x63422f08, 0xa7951fc8)},
+ {TOBN(0x562b24f4, 0x0807e199), TOBN(0xfe9ce5d1, 0x22ad4490),
+ TOBN(0xc2f51b10, 0x0db2b1b4), TOBN(0xeb3613ff, 0xe4541d0d)}},
+ {{TOBN(0xbd2c4a05, 0x2680813b), TOBN(0x527aa55d, 0x561b08d6),
+ TOBN(0xa9f8a40e, 0xa7205558), TOBN(0xe3eea56f, 0x243d0bec)},
+ {TOBN(0x7b853817, 0xa0ff58b3), TOBN(0xb67d3f65, 0x1a69e627),
+ TOBN(0x0b76bbb9, 0xa869b5d6), TOBN(0xa3afeb82, 0x546723ed)}},
+ {{TOBN(0x5f24416d, 0x3e554892), TOBN(0x8413b53d, 0x430e2a45),
+ TOBN(0x99c56aee, 0x9032a2a0), TOBN(0x09432bf6, 0xeec367b1)},
+ {TOBN(0x552850c6, 0xdaf0ecc1), TOBN(0x49ebce55, 0x5bc92048),
+ TOBN(0xdfb66ba6, 0x54811307), TOBN(0x1b84f797, 0x6f298597)}},
+ {{TOBN(0x79590481, 0x8d1d7a0d), TOBN(0xd9fabe03, 0x3a6fa556),
+ TOBN(0xa40f9c59, 0xba9e5d35), TOBN(0xcb1771c1, 0xf6247577)},
+ {TOBN(0x542a47ca, 0xe9a6312b), TOBN(0xa34b3560, 0x552dd8c5),
+ TOBN(0xfdf94de0, 0x0d794716), TOBN(0xd46124a9, 0x9c623094)}},
+ {{TOBN(0x56b7435d, 0x68afe8b4), TOBN(0x27f20540, 0x6c0d8ea1),
+ TOBN(0x12b77e14, 0x73186898), TOBN(0xdbc3dd46, 0x7479490f)},
+ {TOBN(0x951a9842, 0xc03b0c05), TOBN(0x8b1b3bb3, 0x7921bc96),
+ TOBN(0xa573b346, 0x2b202e0a), TOBN(0x77e4665d, 0x47254d56)}},
+ {{TOBN(0x08b70dfc, 0xd23e3984), TOBN(0xab86e8bc, 0xebd14236),
+ TOBN(0xaa3e07f8, 0x57114ba7), TOBN(0x5ac71689, 0xab0ef4f2)},
+ {TOBN(0x88fca384, 0x0139d9af), TOBN(0x72733f88, 0x76644af0),
+ TOBN(0xf122f72a, 0x65d74f4a), TOBN(0x13931577, 0xa5626c7a)}},
+ {{TOBN(0xd5b5d9eb, 0x70f8d5a4), TOBN(0x375adde7, 0xd7bbb228),
+ TOBN(0x31e88b86, 0x0c1c0b32), TOBN(0xd1f568c4, 0x173edbaa)},
+ {TOBN(0x1592fc83, 0x5459df02), TOBN(0x2beac0fb, 0x0fcd9a7e),
+ TOBN(0xb0a6fdb8, 0x1b473b0a), TOBN(0xe3224c6f, 0x0fe8fc48)}},
+ {{TOBN(0x680bd00e, 0xe87edf5b), TOBN(0x30385f02, 0x20e77cf5),
+ TOBN(0xe9ab98c0, 0x4d42d1b2), TOBN(0x72d191d2, 0xd3816d77)},
+ {TOBN(0x1564daca, 0x0917d9e5), TOBN(0x394eab59, 0x1f8fed7f),
+ TOBN(0xa209aa8d, 0x7fbb3896), TOBN(0x5564f3b9, 0xbe6ac98e)}},
+ {{TOBN(0xead21d05, 0xd73654ef), TOBN(0x68d1a9c4, 0x13d78d74),
+ TOBN(0x61e01708, 0x6d4973a0), TOBN(0x83da3500, 0x46e6d32a)},
+ {TOBN(0x6a3dfca4, 0x68ae0118), TOBN(0xa1b9a4c9, 0xd02da069),
+ TOBN(0x0b2ff9c7, 0xebab8302), TOBN(0x98af07c3, 0x944ba436)}},
+ {{TOBN(0x85997326, 0x995f0f9f), TOBN(0x467fade0, 0x71b58bc6),
+ TOBN(0x47e4495a, 0xbd625a2b), TOBN(0xfdd2d01d, 0x33c3b8cd)},
+ {TOBN(0x2c38ae28, 0xc693f9fa), TOBN(0x48622329, 0x348f7999),
+ TOBN(0x97bf738e, 0x2161f583), TOBN(0x15ee2fa7, 0x565e8cc9)}},
+ {{TOBN(0xa1a5c845, 0x5777e189), TOBN(0xcc10bee0, 0x456f2829),
+ TOBN(0x8ad95c56, 0xda762bd5), TOBN(0x152e2214, 0xe9d91da8)},
+ {TOBN(0x975b0e72, 0x7cb23c74), TOBN(0xfd5d7670, 0xa90c66df),
+ TOBN(0xb5b5b8ad, 0x225ffc53), TOBN(0xab6dff73, 0xfaded2ae)}},
+ {{TOBN(0xebd56781, 0x6f4cbe9d), TOBN(0x0ed8b249, 0x6a574bd7),
+ TOBN(0x41c246fe, 0x81a881fa), TOBN(0x91564805, 0xc3db9c70)},
+ {TOBN(0xd7c12b08, 0x5b862809), TOBN(0x1facd1f1, 0x55858d7b),
+ TOBN(0x7693747c, 0xaf09e92a), TOBN(0x3b69dcba, 0x189a425f)}},
+ {{TOBN(0x0be28e9f, 0x967365ef), TOBN(0x57300eb2, 0xe801f5c9),
+ TOBN(0x93b8ac6a, 0xd583352f), TOBN(0xa2cf1f89, 0xcd05b2b7)},
+ {TOBN(0x7c0c9b74, 0x4dcc40cc), TOBN(0xfee38c45, 0xada523fb),
+ TOBN(0xb49a4dec, 0x1099cc4d), TOBN(0x325c377f, 0x69f069c6)}},
+ {{TOBN(0xe12458ce, 0x476cc9ff), TOBN(0x580e0b6c, 0xc6d4cb63),
+ TOBN(0xd561c8b7, 0x9072289b), TOBN(0x0377f264, 0xa619e6da)},
+ {TOBN(0x26685362, 0x88e591a5), TOBN(0xa453a7bd, 0x7523ca2b),
+ TOBN(0x8a9536d2, 0xc1df4533), TOBN(0xc8e50f2f, 0xbe972f79)}},
+ {{TOBN(0xd433e50f, 0x6d3549cf), TOBN(0x6f33696f, 0xfacd665e),
+ TOBN(0x695bfdac, 0xce11fcb4), TOBN(0x810ee252, 0xaf7c9860)},
+ {TOBN(0x65450fe1, 0x7159bb2c), TOBN(0xf7dfbebe, 0x758b357b),
+ TOBN(0x2b057e74, 0xd69fea72), TOBN(0xd485717a, 0x92731745)}}},
+ {{{TOBN(0x896c42e8, 0xee36860c), TOBN(0xdaf04dfd, 0x4113c22d),
+ TOBN(0x1adbb7b7, 0x44104213), TOBN(0xe5fd5fa1, 0x1fd394ea)},
+ {TOBN(0x68235d94, 0x1a4e0551), TOBN(0x6772cfbe, 0x18d10151),
+ TOBN(0x276071e3, 0x09984523), TOBN(0xe4e879de, 0x5a56ba98)}},
+ {{TOBN(0xaaafafb0, 0x285b9491), TOBN(0x01a0be88, 0x1e4c705e),
+ TOBN(0xff1d4f5d, 0x2ad9caab), TOBN(0x6e349a4a, 0xc37a233f)},
+ {TOBN(0xcf1c1246, 0x4a1c6a16), TOBN(0xd99e6b66, 0x29383260),
+ TOBN(0xea3d4366, 0x5f6d5471), TOBN(0x36974d04, 0xff8cc89b)}},
+ {{TOBN(0xc26c49a1, 0xcfe89d80), TOBN(0xb42c026d, 0xda9c8371),
+ TOBN(0xca6c013a, 0xdad066d2), TOBN(0xfb8f7228, 0x56a4f3ee)},
+ {TOBN(0x08b579ec, 0xd850935b), TOBN(0x34c1a74c, 0xd631e1b3),
+ TOBN(0xcb5fe596, 0xac198534), TOBN(0x39ff21f6, 0xe1f24f25)}},
+ {{TOBN(0x27f29e14, 0x8f929057), TOBN(0x7a64ae06, 0xc0c853df),
+ TOBN(0x256cd183, 0x58e9c5ce), TOBN(0x9d9cce82, 0xded092a5)},
+ {TOBN(0xcc6e5979, 0x6e93b7c7), TOBN(0xe1e47092, 0x31bb9e27),
+ TOBN(0xb70b3083, 0xaa9e29a0), TOBN(0xbf181a75, 0x3785e644)}},
+ {{TOBN(0xf53f2c65, 0x8ead09f7), TOBN(0x1335e1d5, 0x9780d14d),
+ TOBN(0x69cc20e0, 0xcd1b66bc), TOBN(0x9b670a37, 0xbbe0bfc8)},
+ {TOBN(0xce53dc81, 0x28efbeed), TOBN(0x0c74e77c, 0x8326a6e5),
+ TOBN(0x3604e0d2, 0xb88e9a63), TOBN(0xbab38fca, 0x13dc2248)}},
+ {{TOBN(0x8ed6e8c8, 0x5c0a3f1e), TOBN(0xbcad2492, 0x7c87c37f),
+ TOBN(0xfdfb62bb, 0x9ee3b78d), TOBN(0xeba8e477, 0xcbceba46)},
+ {TOBN(0x37d38cb0, 0xeeaede4b), TOBN(0x0bc498e8, 0x7976deb6),
+ TOBN(0xb2944c04, 0x6b6147fb), TOBN(0x8b123f35, 0xf71f9609)}},
+ {{TOBN(0xa155dcc7, 0xde79dc24), TOBN(0xf1168a32, 0x558f69cd),
+ TOBN(0xbac21595, 0x0d1850df), TOBN(0x15c8295b, 0xb204c848)},
+ {TOBN(0xf661aa36, 0x7d8184ff), TOBN(0xc396228e, 0x30447bdb),
+ TOBN(0x11cd5143, 0xbde4a59e), TOBN(0xe3a26e3b, 0x6beab5e6)}},
+ {{TOBN(0xd3b3a13f, 0x1402b9d0), TOBN(0x573441c3, 0x2c7bc863),
+ TOBN(0x4b301ec4, 0x578c3e6e), TOBN(0xc26fc9c4, 0x0adaf57e)},
+ {TOBN(0x96e71bfd, 0x7493cea3), TOBN(0xd05d4b3f, 0x1af81456),
+ TOBN(0xdaca2a8a, 0x6a8c608f), TOBN(0x53ef07f6, 0x0725b276)}},
+ {{TOBN(0x07a5fbd2, 0x7824fc56), TOBN(0x34675218, 0x13289077),
+ TOBN(0x5bf69fd5, 0xe0c48349), TOBN(0xa613ddd3, 0xb6aa7875)},
+ {TOBN(0x7f78c19c, 0x5450d866), TOBN(0x46f4409c, 0x8f84a481),
+ TOBN(0x9f1d1928, 0x90fce239), TOBN(0x016c4168, 0xb2ce44b9)}},
+ {{TOBN(0xbae023f0, 0xc7435978), TOBN(0xb152c888, 0x20e30e19),
+ TOBN(0x9c241645, 0xe3fa6faf), TOBN(0x735d95c1, 0x84823e60)},
+ {TOBN(0x03197573, 0x03955317), TOBN(0x0b4b02a9, 0xf03b4995),
+ TOBN(0x076bf559, 0x70274600), TOBN(0x32c5cc53, 0xaaf57508)}},
+ {{TOBN(0xe8af6d1f, 0x60624129), TOBN(0xb7bc5d64, 0x9a5e2b5e),
+ TOBN(0x3814b048, 0x5f082d72), TOBN(0x76f267f2, 0xce19677a)},
+ {TOBN(0x626c630f, 0xb36eed93), TOBN(0x55230cd7, 0x3bf56803),
+ TOBN(0x78837949, 0xce2736a0), TOBN(0x0d792d60, 0xaa6c55f1)}},
+ {{TOBN(0x0318dbfd, 0xd5c7c5d2), TOBN(0xb38f8da7, 0x072b342d),
+ TOBN(0x3569bddc, 0x7b8de38a), TOBN(0xf25b5887, 0xa1c94842)},
+ {TOBN(0xb2d5b284, 0x2946ad60), TOBN(0x854f29ad, 0xe9d1707e),
+ TOBN(0xaa5159dc, 0x2c6a4509), TOBN(0x899f94c0, 0x57189837)}},
+ {{TOBN(0xcf6adc51, 0xf4a55b03), TOBN(0x261762de, 0x35e3b2d5),
+ TOBN(0x4cc43012, 0x04827b51), TOBN(0xcd22a113, 0xc6021442)},
+ {TOBN(0xce2fd61a, 0x247c9569), TOBN(0x59a50973, 0xd152beca),
+ TOBN(0x6c835a11, 0x63a716d4), TOBN(0xc26455ed, 0x187dedcf)}},
+ {{TOBN(0x27f536e0, 0x49ce89e7), TOBN(0x18908539, 0xcc890cb5),
+ TOBN(0x308909ab, 0xd83c2aa1), TOBN(0xecd3142b, 0x1ab73bd3)},
+ {TOBN(0x6a85bf59, 0xb3f5ab84), TOBN(0x3c320a68, 0xf2bea4c6),
+ TOBN(0xad8dc538, 0x6da4541f), TOBN(0xeaf34eb0, 0xb7c41186)}},
+ {{TOBN(0x1c780129, 0x977c97c4), TOBN(0x5ff9beeb, 0xc57eb9fa),
+ TOBN(0xa24d0524, 0xc822c478), TOBN(0xfd8eec2a, 0x461cd415)},
+ {TOBN(0xfbde194e, 0xf027458c), TOBN(0xb4ff5319, 0x1d1be115),
+ TOBN(0x63f874d9, 0x4866d6f4), TOBN(0x35c75015, 0xb21ad0c9)}},
+ {{TOBN(0xa6b5c9d6, 0x46ac49d2), TOBN(0x42c77c0b, 0x83137aa9),
+ TOBN(0x24d000fc, 0x68225a38), TOBN(0x0f63cfc8, 0x2fe1e907)},
+ {TOBN(0x22d1b01b, 0xc6441f95), TOBN(0x7d38f719, 0xec8e448f),
+ TOBN(0x9b33fa5f, 0x787fb1ba), TOBN(0x94dcfda1, 0x190158df)}},
+ {{TOBN(0xc47cb339, 0x5f6d4a09), TOBN(0x6b4f355c, 0xee52b826),
+ TOBN(0x3d100f5d, 0xf51b930a), TOBN(0xf4512fac, 0x9f668f69)},
+ {TOBN(0x546781d5, 0x206c4c74), TOBN(0xd021d4d4, 0xcb4d2e48),
+ TOBN(0x494a54c2, 0xca085c2d), TOBN(0xf1dbaca4, 0x520850a8)}},
+ {{TOBN(0x63c79326, 0x490a1aca), TOBN(0xcb64dd9c, 0x41526b02),
+ TOBN(0xbb772591, 0xa2979258), TOBN(0x3f582970, 0x48d97846)},
+ {TOBN(0xd66b70d1, 0x7c213ba7), TOBN(0xc28febb5, 0xe8a0ced4),
+ TOBN(0x6b911831, 0xc10338c1), TOBN(0x0d54e389, 0xbf0126f3)}},
+ {{TOBN(0x7048d460, 0x4af206ee), TOBN(0x786c88f6, 0x77e97cb9),
+ TOBN(0xd4375ae1, 0xac64802e), TOBN(0x469bcfe1, 0xd53ec11c)},
+ {TOBN(0xfc9b340d, 0x47062230), TOBN(0xe743bb57, 0xc5b4a3ac),
+ TOBN(0xfe00b4aa, 0x59ef45ac), TOBN(0x29a4ef23, 0x59edf188)}},
+ {{TOBN(0x40242efe, 0xb483689b), TOBN(0x2575d3f6, 0x513ac262),
+ TOBN(0xf30037c8, 0x0ca6db72), TOBN(0xc9fcce82, 0x98864be2)},
+ {TOBN(0x84a112ff, 0x0149362d), TOBN(0x95e57582, 0x1c4ae971),
+ TOBN(0x1fa4b1a8, 0x945cf86c), TOBN(0x4525a734, 0x0b024a2f)}},
+ {{TOBN(0xe76c8b62, 0x8f338360), TOBN(0x483ff593, 0x28edf32b),
+ TOBN(0x67e8e90a, 0x298b1aec), TOBN(0x9caab338, 0x736d9a21)},
+ {TOBN(0x5c09d2fd, 0x66892709), TOBN(0x2496b4dc, 0xb55a1d41),
+ TOBN(0x93f5fb1a, 0xe24a4394), TOBN(0x08c75049, 0x6fa8f6c1)}},
+ {{TOBN(0xcaead1c2, 0xc905d85f), TOBN(0xe9d7f790, 0x0733ae57),
+ TOBN(0x24c9a65c, 0xf07cdd94), TOBN(0x7389359c, 0xa4b55931)},
+ {TOBN(0xf58709b7, 0x367e45f7), TOBN(0x1f203067, 0xcb7e7adc),
+ TOBN(0x82444bff, 0xc7b72818), TOBN(0x07303b35, 0xbaac8033)}},
+ {{TOBN(0x1e1ee4e4, 0xd13b7ea1), TOBN(0xe6489b24, 0xe0e74180),
+ TOBN(0xa5f2c610, 0x7e70ef70), TOBN(0xa1655412, 0xbdd10894)},
+ {TOBN(0x555ebefb, 0x7af4194e), TOBN(0x533c1c3c, 0x8e89bd9c),
+ TOBN(0x735b9b57, 0x89895856), TOBN(0x15fb3cd2, 0x567f5c15)}},
+ {{TOBN(0x057fed45, 0x526f09fd), TOBN(0xe8a4f10c, 0x8128240a),
+ TOBN(0x9332efc4, 0xff2bfd8d), TOBN(0x214e77a0, 0xbd35aa31)},
+ {TOBN(0x32896d73, 0x14faa40e), TOBN(0x767867ec, 0x01e5f186),
+ TOBN(0xc9adf8f1, 0x17a1813e), TOBN(0xcb6cda78, 0x54741795)}},
+ {{TOBN(0xb7521b6d, 0x349d51aa), TOBN(0xf56b5a9e, 0xe3c7b8e9),
+ TOBN(0xc6f1e5c9, 0x32a096df), TOBN(0x083667c4, 0xa3635024)},
+ {TOBN(0x365ea135, 0x18087f2f), TOBN(0xf1b8eaac, 0xd136e45d),
+ TOBN(0xc8a0e484, 0x73aec989), TOBN(0xd75a324b, 0x142c9259)}},
+ {{TOBN(0xb7b4d001, 0x01dae185), TOBN(0x45434e0b, 0x9b7a94bc),
+ TOBN(0xf54339af, 0xfbd8cb0b), TOBN(0xdcc4569e, 0xe98ef49e)},
+ {TOBN(0x7789318a, 0x09a51299), TOBN(0x81b4d206, 0xb2b025d8),
+ TOBN(0xf64aa418, 0xfae85792), TOBN(0x3e50258f, 0xacd7baf7)}},
+ {{TOBN(0xdce84cdb, 0x2996864b), TOBN(0xa2e67089, 0x1f485fa4),
+ TOBN(0xb28b2bb6, 0x534c6a5a), TOBN(0x31a7ec6b, 0xc94b9d39)},
+ {TOBN(0x1d217766, 0xd6bc20da), TOBN(0x4acdb5ec, 0x86761190),
+ TOBN(0x68726328, 0x73701063), TOBN(0x4d24ee7c, 0x2128c29b)}},
+ {{TOBN(0xc072ebd3, 0xa19fd868), TOBN(0x612e481c, 0xdb8ddd3b),
+ TOBN(0xb4e1d754, 0x1a64d852), TOBN(0x00ef95ac, 0xc4c6c4ab)},
+ {TOBN(0x1536d2ed, 0xaa0a6c46), TOBN(0x61294086, 0x43774790),
+ TOBN(0x54af25e8, 0x343fda10), TOBN(0x9ff9d98d, 0xfd25d6f2)}},
+ {{TOBN(0x0746af7c, 0x468b8835), TOBN(0x977a31cb, 0x730ecea7),
+ TOBN(0xa5096b80, 0xc2cf4a81), TOBN(0xaa986833, 0x6458c37a)},
+ {TOBN(0x6af29bf3, 0xa6bd9d34), TOBN(0x6a62fe9b, 0x33c5d854),
+ TOBN(0x50e6c304, 0xb7133b5e), TOBN(0x04b60159, 0x7d6e6848)}},
+ {{TOBN(0x4cd296df, 0x5579bea4), TOBN(0x10e35ac8, 0x5ceedaf1),
+ TOBN(0x04c4c5fd, 0xe3bcc5b1), TOBN(0x95f9ee8a, 0x89412cf9)},
+ {TOBN(0x2c9459ee, 0x82b6eb0f), TOBN(0x2e845765, 0x95c2aadd),
+ TOBN(0x774a84ae, 0xd327fcfe), TOBN(0xd8c93722, 0x0368d476)}},
+ {{TOBN(0x0dbd5748, 0xf83e8a3b), TOBN(0xa579aa96, 0x8d2495f3),
+ TOBN(0x535996a0, 0xae496e9b), TOBN(0x07afbfe9, 0xb7f9bcc2)},
+ {TOBN(0x3ac1dc6d, 0x5b7bd293), TOBN(0x3b592cff, 0x7022323d),
+ TOBN(0xba0deb98, 0x9c0a3e76), TOBN(0x18e78e9f, 0x4b197acb)}},
+ {{TOBN(0x211cde10, 0x296c36ef), TOBN(0x7ee89672, 0x82c4da77),
+ TOBN(0xb617d270, 0xa57836da), TOBN(0xf0cd9c31, 0x9cb7560b)},
+ {TOBN(0x01fdcbf7, 0xe455fe90), TOBN(0x3fb53cbb, 0x7e7334f3),
+ TOBN(0x781e2ea4, 0x4e7de4ec), TOBN(0x8adab3ad, 0x0b384fd0)}},
+ {{TOBN(0x129eee2f, 0x53d64829), TOBN(0x7a471e17, 0xa261492b),
+ TOBN(0xe4f9adb9, 0xe4cb4a2c), TOBN(0x3d359f6f, 0x97ba2c2d)},
+ {TOBN(0x346c6786, 0x0aacd697), TOBN(0x92b444c3, 0x75c2f8a8),
+ TOBN(0xc79fa117, 0xd85df44e), TOBN(0x56782372, 0x398ddf31)}},
+ {{TOBN(0x60e690f2, 0xbbbab3b8), TOBN(0x4851f8ae, 0x8b04816b),
+ TOBN(0xc72046ab, 0x9c92e4d2), TOBN(0x518c74a1, 0x7cf3136b)},
+ {TOBN(0xff4eb50a, 0xf9877d4c), TOBN(0x14578d90, 0xa919cabb),
+ TOBN(0x8218f8c4, 0xac5eb2b6), TOBN(0xa3ccc547, 0x542016e4)}},
+ {{TOBN(0x025bf48e, 0x327f8349), TOBN(0xf3e97346, 0xf43cb641),
+ TOBN(0xdc2bafdf, 0x500f1085), TOBN(0x57167876, 0x2f063055)},
+ {TOBN(0x5bd914b9, 0x411925a6), TOBN(0x7c078d48, 0xa1123de5),
+ TOBN(0xee6bf835, 0x182b165d), TOBN(0xb11b5e5b, 0xba519727)}},
+ {{TOBN(0xe33ea76c, 0x1eea7b85), TOBN(0x2352b461, 0x92d4f85e),
+ TOBN(0xf101d334, 0xafe115bb), TOBN(0xfabc1294, 0x889175a3)},
+ {TOBN(0x7f6bcdc0, 0x5233f925), TOBN(0xe0a802db, 0xe77fec55),
+ TOBN(0xbdb47b75, 0x8069b659), TOBN(0x1c5e12de, 0xf98fbd74)}},
+ {{TOBN(0x869c58c6, 0x4b8457ee), TOBN(0xa5360f69, 0x4f7ea9f7),
+ TOBN(0xe576c09f, 0xf460b38f), TOBN(0x6b70d548, 0x22b7fb36)},
+ {TOBN(0x3fd237f1, 0x3bfae315), TOBN(0x33797852, 0xcbdff369),
+ TOBN(0x97df25f5, 0x25b516f9), TOBN(0x46f388f2, 0xba38ad2d)}},
+ {{TOBN(0x656c4658, 0x89d8ddbb), TOBN(0x8830b26e, 0x70f38ee8),
+ TOBN(0x4320fd5c, 0xde1212b0), TOBN(0xc34f30cf, 0xe4a2edb2)},
+ {TOBN(0xabb131a3, 0x56ab64b8), TOBN(0x7f77f0cc, 0xd99c5d26),
+ TOBN(0x66856a37, 0xbf981d94), TOBN(0x19e76d09, 0x738bd76e)}},
+ {{TOBN(0xe76c8ac3, 0x96238f39), TOBN(0xc0a482be, 0xa830b366),
+ TOBN(0xb7b8eaff, 0x0b4eb499), TOBN(0x8ecd83bc, 0x4bfb4865)},
+ {TOBN(0x971b2cb7, 0xa2f3776f), TOBN(0xb42176a4, 0xf4b88adf),
+ TOBN(0xb9617df5, 0xbe1fa446), TOBN(0x8b32d508, 0xcd031bd2)}},
+ {{TOBN(0x1c6bd47d, 0x53b618c0), TOBN(0xc424f46c, 0x6a227923),
+ TOBN(0x7303ffde, 0xdd92d964), TOBN(0xe9712878, 0x71b5abf2)},
+ {TOBN(0x8f48a632, 0xf815561d), TOBN(0x85f48ff5, 0xd3c055d1),
+ TOBN(0x222a1427, 0x7525684f), TOBN(0xd0d841a0, 0x67360cc3)}},
+ {{TOBN(0x4245a926, 0x0b9267c6), TOBN(0xc78913f1, 0xcf07f863),
+ TOBN(0xaa844c8e, 0x4d0d9e24), TOBN(0xa42ad522, 0x3d5f9017)},
+ {TOBN(0xbd371749, 0xa2c989d5), TOBN(0x928292df, 0xe1f5e78e),
+ TOBN(0x493b383e, 0x0a1ea6da), TOBN(0x5136fd8d, 0x13aee529)}},
+ {{TOBN(0x860c44b1, 0xf2c34a99), TOBN(0x3b00aca4, 0xbf5855ac),
+ TOBN(0xabf6aaa0, 0xfaaf37be), TOBN(0x65f43682, 0x2a53ec08)},
+ {TOBN(0x1d9a5801, 0xa11b12e1), TOBN(0x78a7ab2c, 0xe20ed475),
+ TOBN(0x0de1067e, 0x9a41e0d5), TOBN(0x30473f5f, 0x305023ea)}},
+ {{TOBN(0xdd3ae09d, 0x169c7d97), TOBN(0x5cd5baa4, 0xcfaef9cd),
+ TOBN(0x5cd7440b, 0x65a44803), TOBN(0xdc13966a, 0x47f364de)},
+ {TOBN(0x077b2be8, 0x2b8357c1), TOBN(0x0cb1b4c5, 0xe9d57c2a),
+ TOBN(0x7a4ceb32, 0x05ff363e), TOBN(0xf310fa4d, 0xca35a9ef)}},
+ {{TOBN(0xdbb7b352, 0xf97f68c6), TOBN(0x0c773b50, 0x0b02cf58),
+ TOBN(0xea2e4821, 0x3c1f96d9), TOBN(0xffb357b0, 0xeee01815)},
+ {TOBN(0xb9c924cd, 0xe0f28039), TOBN(0x0b36c95a, 0x46a3fbe4),
+ TOBN(0x1faaaea4, 0x5e46db6c), TOBN(0xcae575c3, 0x1928aaff)}},
+ {{TOBN(0x7f671302, 0xa70dab86), TOBN(0xfcbd12a9, 0x71c58cfc),
+ TOBN(0xcbef9acf, 0xbee0cb92), TOBN(0x573da0b9, 0xf8c1b583)},
+ {TOBN(0x4752fcfe, 0x0d41d550), TOBN(0xe7eec0e3, 0x2155cffe),
+ TOBN(0x0fc39fcb, 0x545ae248), TOBN(0x522cb8d1, 0x8065f44e)}},
+ {{TOBN(0x263c962a, 0x70cbb96c), TOBN(0xe034362a, 0xbcd124a9),
+ TOBN(0xf120db28, 0x3c2ae58d), TOBN(0xb9a38d49, 0xfef6d507)},
+ {TOBN(0xb1fd2a82, 0x1ff140fd), TOBN(0xbd162f30, 0x20aee7e0),
+ TOBN(0x4e17a5d4, 0xcb251949), TOBN(0x2aebcb83, 0x4f7e1c3d)}},
+ {{TOBN(0x608eb25f, 0x937b0527), TOBN(0xf42e1e47, 0xeb7d9997),
+ TOBN(0xeba699c4, 0xb8a53a29), TOBN(0x1f921c71, 0xe091b536)},
+ {TOBN(0xcce29e7b, 0x5b26bbd5), TOBN(0x7a8ef5ed, 0x3b61a680),
+ TOBN(0xe5ef8043, 0xba1f1c7e), TOBN(0x16ea8217, 0x18158dda)}},
+ {{TOBN(0x01778a2b, 0x599ff0f9), TOBN(0x68a923d7, 0x8104fc6b),
+ TOBN(0x5bfa44df, 0xda694ff3), TOBN(0x4f7199db, 0xf7667f12)},
+ {TOBN(0xc06d8ff6, 0xe46f2a79), TOBN(0x08b5dead, 0xe9f8131d),
+ TOBN(0x02519a59, 0xabb4ce7c), TOBN(0xc4f710bc, 0xb42aec3e)}},
+ {{TOBN(0x3d77b057, 0x78bde41a), TOBN(0x6474bf80, 0xb4186b5a),
+ TOBN(0x048b3f67, 0x88c65741), TOBN(0xc64519de, 0x03c7c154)},
+ {TOBN(0xdf073846, 0x0edfcc4f), TOBN(0x319aa737, 0x48f1aa6b),
+ TOBN(0x8b9f8a02, 0xca909f77), TOBN(0x90258139, 0x7580bfef)}},
+ {{TOBN(0xd8bfd3ca, 0xc0c22719), TOBN(0xc60209e4, 0xc9ca151e),
+ TOBN(0x7a744ab5, 0xd9a1a69c), TOBN(0x6de5048b, 0x14937f8f)},
+ {TOBN(0x171938d8, 0xe115ac04), TOBN(0x7df70940, 0x1c6b16d2),
+ TOBN(0xa6aeb663, 0x7f8e94e7), TOBN(0xc130388e, 0x2a2cf094)}},
+ {{TOBN(0x1850be84, 0x77f54e6e), TOBN(0x9f258a72, 0x65d60fe5),
+ TOBN(0xff7ff0c0, 0x6c9146d6), TOBN(0x039aaf90, 0xe63a830b)},
+ {TOBN(0x38f27a73, 0x9460342f), TOBN(0x4703148c, 0x3f795f8a),
+ TOBN(0x1bb5467b, 0x9681a97e), TOBN(0x00931ba5, 0xecaeb594)}},
+ {{TOBN(0xcdb6719d, 0x786f337c), TOBN(0xd9c01cd2, 0xe704397d),
+ TOBN(0x0f4a3f20, 0x555c2fef), TOBN(0x00452509, 0x7c0af223)},
+ {TOBN(0x54a58047, 0x84db8e76), TOBN(0x3bacf1aa, 0x93c8aa06),
+ TOBN(0x11ca957c, 0xf7919422), TOBN(0x50641053, 0x78cdaa40)}},
+ {{TOBN(0x7a303874, 0x9f7144ae), TOBN(0x170c963f, 0x43d4acfd),
+ TOBN(0x5e148149, 0x58ddd3ef), TOBN(0xa7bde582, 0x9e72dba8)},
+ {TOBN(0x0769da8b, 0x6fa68750), TOBN(0xfa64e532, 0x572e0249),
+ TOBN(0xfcaadf9d, 0x2619ad31), TOBN(0x87882daa, 0xa7b349cd)}},
+ {{TOBN(0x9f6eb731, 0x6c67a775), TOBN(0xcb10471a, 0xefc5d0b1),
+ TOBN(0xb433750c, 0xe1b806b2), TOBN(0x19c5714d, 0x57b1ae7e)},
+ {TOBN(0xc0dc8b7b, 0xed03fd3f), TOBN(0xdd03344f, 0x31bc194e),
+ TOBN(0xa66c52a7, 0x8c6320b5), TOBN(0x8bc82ce3, 0xd0b6fd93)}},
+ {{TOBN(0xf8e13501, 0xb35f1341), TOBN(0xe53156dd, 0x25a43e42),
+ TOBN(0xd3adf27e, 0x4daeb85c), TOBN(0xb81d8379, 0xbbeddeb5)},
+ {TOBN(0x1b0b546e, 0x2e435867), TOBN(0x9020eb94, 0xeba5dd60),
+ TOBN(0x37d91161, 0x8210cb9d), TOBN(0x4c596b31, 0x5c91f1cf)}},
+ {{TOBN(0xb228a90f, 0x0e0b040d), TOBN(0xbaf02d82, 0x45ff897f),
+ TOBN(0x2aac79e6, 0x00fa6122), TOBN(0x24828817, 0x8e36f557)},
+ {TOBN(0xb9521d31, 0x113ec356), TOBN(0x9e48861e, 0x15eff1f8),
+ TOBN(0x2aa1d412, 0xe0d41715), TOBN(0x71f86203, 0x53f131b8)}},
+ {{TOBN(0xf60da8da, 0x3fd19408), TOBN(0x4aa716dc, 0x278d9d99),
+ TOBN(0x394531f7, 0xa8c51c90), TOBN(0xb560b0e8, 0xf59db51c)},
+ {TOBN(0xa28fc992, 0xfa34bdad), TOBN(0xf024fa14, 0x9cd4f8bd),
+ TOBN(0x5cf530f7, 0x23a9d0d3), TOBN(0x615ca193, 0xe28c9b56)}},
+ {{TOBN(0x6d2a483d, 0x6f73c51e), TOBN(0xa4cb2412, 0xea0dc2dd),
+ TOBN(0x50663c41, 0x1eb917ff), TOBN(0x3d3a74cf, 0xeade299e)},
+ {TOBN(0x29b3990f, 0x4a7a9202), TOBN(0xa9bccf59, 0xa7b15c3d),
+ TOBN(0x66a3ccdc, 0xa5df9208), TOBN(0x48027c14, 0x43f2f929)}},
+ {{TOBN(0xd385377c, 0x40b557f0), TOBN(0xe001c366, 0xcd684660),
+ TOBN(0x1b18ed6b, 0xe2183a27), TOBN(0x879738d8, 0x63210329)},
+ {TOBN(0xa687c74b, 0xbda94882), TOBN(0xd1bbcc48, 0xa684b299),
+ TOBN(0xaf6f1112, 0x863b3724), TOBN(0x6943d1b4, 0x2c8ce9f8)}},
+ {{TOBN(0xe044a3bb, 0x098cafb4), TOBN(0x27ed2310, 0x60d48caf),
+ TOBN(0x542b5675, 0x3a31b84d), TOBN(0xcbf3dd50, 0xfcddbed7)},
+ {TOBN(0x25031f16, 0x41b1d830), TOBN(0xa7ec851d, 0xcb0c1e27),
+ TOBN(0xac1c8fe0, 0xb5ae75db), TOBN(0xb24c7557, 0x08c52120)}},
+ {{TOBN(0x57f811dc, 0x1d4636c3), TOBN(0xf8436526, 0x681a9939),
+ TOBN(0x1f6bc6d9, 0x9c81adb3), TOBN(0x840f8ac3, 0x5b7d80d4)},
+ {TOBN(0x731a9811, 0xf4387f1a), TOBN(0x7c501cd3, 0xb5156880),
+ TOBN(0xa5ca4a07, 0xdfe68867), TOBN(0xf123d8f0, 0x5fcea120)}},
+ {{TOBN(0x1fbb0e71, 0xd607039e), TOBN(0x2b70e215, 0xcd3a4546),
+ TOBN(0x32d2f01d, 0x53324091), TOBN(0xb796ff08, 0x180ab19b)},
+ {TOBN(0x32d87a86, 0x3c57c4aa), TOBN(0x2aed9caf, 0xb7c49a27),
+ TOBN(0x9fb35eac, 0x31630d98), TOBN(0x338e8cdf, 0x5c3e20a3)}},
+ {{TOBN(0x80f16182, 0x66cde8db), TOBN(0x4e159980, 0x2d72fd36),
+ TOBN(0xd7b8f13b, 0x9b6e5072), TOBN(0xf5213907, 0x3b7b5dc1)},
+ {TOBN(0x4d431f1d, 0x8ce4396e), TOBN(0x37a1a680, 0xa7ed2142),
+ TOBN(0xbf375696, 0xd01aaf6b), TOBN(0xaa1c0c54, 0xe63aab66)}},
+ {{TOBN(0x3014368b, 0x4ed80940), TOBN(0x67e6d056, 0x7a6fcedd),
+ TOBN(0x7c208c49, 0xca97579f), TOBN(0xfe3d7a81, 0xa23597f6)},
+ {TOBN(0x5e203202, 0x7e096ae2), TOBN(0xb1f3e1e7, 0x24b39366),
+ TOBN(0x26da26f3, 0x2fdcdffc), TOBN(0x79422f1d, 0x6097be83)}}},
+ {{{TOBN(0x263a2cfb, 0x9db3b381), TOBN(0x9c3a2dee, 0xd4df0a4b),
+ TOBN(0x728d06e9, 0x7d04e61f), TOBN(0x8b1adfbc, 0x42449325)},
+ {TOBN(0x6ec1d939, 0x7e053a1b), TOBN(0xee2be5c7, 0x66daf707),
+ TOBN(0x80ba1e14, 0x810ac7ab), TOBN(0xdd2ae778, 0xf530f174)}},
+ {{TOBN(0x0435d97a, 0x205b9d8b), TOBN(0x6eb8f064, 0x056756d4),
+ TOBN(0xd5e88a8b, 0xb6f8210e), TOBN(0x070ef12d, 0xec9fd9ea)},
+ {TOBN(0x4d849505, 0x3bcc876a), TOBN(0x12a75338, 0xa7404ce3),
+ TOBN(0xd22b49e1, 0xb8a1db5e), TOBN(0xec1f2051, 0x14bfa5ad)}},
+ {{TOBN(0xadbaeb79, 0xb6828f36), TOBN(0x9d7a0258, 0x01bd5b9e),
+ TOBN(0xeda01e0d, 0x1e844b0c), TOBN(0x4b625175, 0x887edfc9)},
+ {TOBN(0x14109fdd, 0x9669b621), TOBN(0x88a2ca56, 0xf6f87b98),
+ TOBN(0xfe2eb788, 0x170df6bc), TOBN(0x0cea06f4, 0xffa473f9)}},
+ {{TOBN(0x43ed81b5, 0xc4e83d33), TOBN(0xd9f35879, 0x5efd488b),
+ TOBN(0x164a620f, 0x9deb4d0f), TOBN(0xc6927bdb, 0xac6a7394)},
+ {TOBN(0x45c28df7, 0x9f9e0f03), TOBN(0x2868661e, 0xfcd7e1a9),
+ TOBN(0x7cf4e8d0, 0xffa348f1), TOBN(0x6bd4c284, 0x398538e0)}},
+ {{TOBN(0x2618a091, 0x289a8619), TOBN(0xef796e60, 0x6671b173),
+ TOBN(0x664e46e5, 0x9090c632), TOBN(0xa38062d4, 0x1e66f8fb)},
+ {TOBN(0x6c744a20, 0x0573274e), TOBN(0xd07b67e4, 0xa9271394),
+ TOBN(0x391223b2, 0x6bdc0e20), TOBN(0xbe2d93f1, 0xeb0a05a7)}},
+ {{TOBN(0xf23e2e53, 0x3f36d141), TOBN(0xe84bb3d4, 0x4dfca442),
+ TOBN(0xb804a48d, 0x6b7c023a), TOBN(0x1e16a8fa, 0x76431c3b)},
+ {TOBN(0x1b5452ad, 0xddd472e0), TOBN(0x7d405ee7, 0x0d1ee127),
+ TOBN(0x50fc6f1d, 0xffa27599), TOBN(0x351ac53c, 0xbf391b35)}},
+ {{TOBN(0x7efa14b8, 0x4444896b), TOBN(0x64974d2f, 0xf94027fb),
+ TOBN(0xefdcd0e8, 0xde84487d), TOBN(0x8c45b260, 0x2b48989b)},
+ {TOBN(0xa8fcbbc2, 0xd8463487), TOBN(0xd1b2b3f7, 0x3fbc476c),
+ TOBN(0x21d005b7, 0xc8f443c0), TOBN(0x518f2e67, 0x40c0139c)}},
+ {{TOBN(0x56036e8c, 0x06d75fc1), TOBN(0x2dcf7bb7, 0x3249a89f),
+ TOBN(0x81dd1d3d, 0xe245e7dd), TOBN(0xf578dc4b, 0xebd6e2a7)},
+ {TOBN(0x4c028903, 0xdf2ce7a0), TOBN(0xaee36288, 0x9c39afac),
+ TOBN(0xdc847c31, 0x146404ab), TOBN(0x6304c0d8, 0xa4e97818)}},
+ {{TOBN(0xae51dca2, 0xa91f6791), TOBN(0x2abe4190, 0x9baa9efc),
+ TOBN(0xd9d2e2f4, 0x559c7ac1), TOBN(0xe82f4b51, 0xfc9f773a)},
+ {TOBN(0xa7713027, 0x4073e81c), TOBN(0xc0276fac, 0xfbb596fc),
+ TOBN(0x1d819fc9, 0xa684f70c), TOBN(0x29b47fdd, 0xc9f7b1e0)}},
+ {{TOBN(0x358de103, 0x459b1940), TOBN(0xec881c59, 0x5b013e93),
+ TOBN(0x51574c93, 0x49532ad3), TOBN(0x2db1d445, 0xb37b46de)},
+ {TOBN(0xc6445b87, 0xdf239fd8), TOBN(0xc718af75, 0x151d24ee),
+ TOBN(0xaea1c4a4, 0xf43c6259), TOBN(0x40c0e5d7, 0x70be02f7)}},
+ {{TOBN(0x6a4590f4, 0x721b33f2), TOBN(0x2124f1fb, 0xfedf04ea),
+ TOBN(0xf8e53cde, 0x9745efe7), TOBN(0xe7e10432, 0x65f046d9)},
+ {TOBN(0xc3fca28e, 0xe4d0c7e6), TOBN(0x847e339a, 0x87253b1b),
+ TOBN(0x9b595348, 0x3743e643), TOBN(0xcb6a0a0b, 0x4fd12fc5)}},
+ {{TOBN(0xfb6836c3, 0x27d02dcc), TOBN(0x5ad00982, 0x7a68bcc2),
+ TOBN(0x1b24b44c, 0x005e912d), TOBN(0xcc83d20f, 0x811fdcfe)},
+ {TOBN(0x36527ec1, 0x666fba0c), TOBN(0x69948197, 0x14754635),
+ TOBN(0xfcdcb1a8, 0x556da9c2), TOBN(0xa5934267, 0x81a732b2)}},
+ {{TOBN(0xec1214ed, 0xa714181d), TOBN(0x609ac13b, 0x6067b341),
+ TOBN(0xff4b4c97, 0xa545df1f), TOBN(0xa1240501, 0x34d2076b)},
+ {TOBN(0x6efa0c23, 0x1409ca97), TOBN(0x254cc1a8, 0x20638c43),
+ TOBN(0xd4e363af, 0xdcfb46cd), TOBN(0x62c2adc3, 0x03942a27)}},
+ {{TOBN(0xc67b9df0, 0x56e46483), TOBN(0xa55abb20, 0x63736356),
+ TOBN(0xab93c098, 0xc551bc52), TOBN(0x382b49f9, 0xb15fe64b)},
+ {TOBN(0x9ec221ad, 0x4dff8d47), TOBN(0x79caf615, 0x437df4d6),
+ TOBN(0x5f13dc64, 0xbb456509), TOBN(0xe4c589d9, 0x191f0714)}},
+ {{TOBN(0x27b6a8ab, 0x3fd40e09), TOBN(0xe455842e, 0x77313ea9),
+ TOBN(0x8b51d1e2, 0x1f55988b), TOBN(0x5716dd73, 0x062bbbfc)},
+ {TOBN(0x633c11e5, 0x4e8bf3de), TOBN(0x9a0e77b6, 0x1b85be3b),
+ TOBN(0x56510729, 0x0911cca6), TOBN(0x27e76495, 0xefa6590f)}},
+ {{TOBN(0xe4ac8b33, 0x070d3aab), TOBN(0x2643672b, 0x9a2cd5e5),
+ TOBN(0x52eff79b, 0x1cfc9173), TOBN(0x665ca49b, 0x90a7c13f)},
+ {TOBN(0x5a8dda59, 0xb3efb998), TOBN(0x8a5b922d, 0x052f1341),
+ TOBN(0xae9ebbab, 0x3cf9a530), TOBN(0x35986e7b, 0xf56da4d7)}},
+ {{TOBN(0x3a636b5c, 0xff3513cc), TOBN(0xbb0cf8ba, 0x3198f7dd),
+ TOBN(0xb8d40522, 0x41f16f86), TOBN(0x760575d8, 0xde13a7bf)},
+ {TOBN(0x36f74e16, 0x9f7aa181), TOBN(0x163a3ecf, 0xf509ed1c),
+ TOBN(0x6aead61f, 0x3c40a491), TOBN(0x158c95fc, 0xdfe8fcaa)}},
+ {{TOBN(0xa3991b6e, 0x13cda46f), TOBN(0x79482415, 0x342faed0),
+ TOBN(0xf3ba5bde, 0x666b5970), TOBN(0x1d52e6bc, 0xb26ab6dd)},
+ {TOBN(0x768ba1e7, 0x8608dd3d), TOBN(0x4930db2a, 0xea076586),
+ TOBN(0xd9575714, 0xe7dc1afa), TOBN(0x1fc7bf7d, 0xf7c58817)}},
+ {{TOBN(0x6b47accd, 0xd9eee96c), TOBN(0x0ca277fb, 0xe58cec37),
+ TOBN(0x113fe413, 0xe702c42a), TOBN(0xdd1764ee, 0xc47cbe51)},
+ {TOBN(0x041e7cde, 0x7b3ed739), TOBN(0x50cb7459, 0x5ce9e1c0),
+ TOBN(0x35568513, 0x2925b212), TOBN(0x7cff95c4, 0x001b081c)}},
+ {{TOBN(0x63ee4cbd, 0x8088b454), TOBN(0xdb7f32f7, 0x9a9e0c8a),
+ TOBN(0xb377d418, 0x6b2447cb), TOBN(0xe3e982aa, 0xd370219b)},
+ {TOBN(0x06ccc1e4, 0xc2a2a593), TOBN(0x72c36865, 0x0773f24f),
+ TOBN(0xa13b4da7, 0x95859423), TOBN(0x8bbf1d33, 0x75040c8f)}},
+ {{TOBN(0x726f0973, 0xda50c991), TOBN(0x48afcd5b, 0x822d6ee2),
+ TOBN(0xe5fc718b, 0x20fd7771), TOBN(0xb9e8e77d, 0xfd0807a1)},
+ {TOBN(0x7f5e0f44, 0x99a7703d), TOBN(0x6972930e, 0x618e36f3),
+ TOBN(0x2b7c77b8, 0x23807bbe), TOBN(0xe5b82405, 0xcb27ff50)}},
+ {{TOBN(0xba8b8be3, 0xbd379062), TOBN(0xd64b7a1d, 0x2dce4a92),
+ TOBN(0x040a73c5, 0xb2952e37), TOBN(0x0a9e252e, 0xd438aeca)},
+ {TOBN(0xdd43956b, 0xc39d3bcb), TOBN(0x1a31ca00, 0xb32b2d63),
+ TOBN(0xd67133b8, 0x5c417a18), TOBN(0xd08e4790, 0x2ef442c8)}},
+ {{TOBN(0x98cb1ae9, 0x255c0980), TOBN(0x4bd86381, 0x2b4a739f),
+ TOBN(0x5a5c31e1, 0x1e4a45a1), TOBN(0x1e5d55fe, 0x9cb0db2f)},
+ {TOBN(0x74661b06, 0x8ff5cc29), TOBN(0x026b389f, 0x0eb8a4f4),
+ TOBN(0x536b21a4, 0x58848c24), TOBN(0x2e5bf8ec, 0x81dc72b0)}},
+ {{TOBN(0x03c187d0, 0xad886aac), TOBN(0x5c16878a, 0xb771b645),
+ TOBN(0xb07dfc6f, 0xc74045ab), TOBN(0x2c6360bf, 0x7800caed)},
+ {TOBN(0x24295bb5, 0xb9c972a3), TOBN(0xc9e6f88e, 0x7c9a6dba),
+ TOBN(0x90ffbf24, 0x92a79aa6), TOBN(0xde29d50a, 0x41c26ac2)}},
+ {{TOBN(0x9f0af483, 0xd309cbe6), TOBN(0x5b020d8a, 0xe0bced4f),
+ TOBN(0x606e986d, 0xb38023e3), TOBN(0xad8f2c9d, 0x1abc6933)},
+ {TOBN(0x19292e1d, 0xe7400e93), TOBN(0xfe3e18a9, 0x52be5e4d),
+ TOBN(0xe8e9771d, 0x2e0680bf), TOBN(0x8c5bec98, 0xc54db063)}},
+ {{TOBN(0x2af9662a, 0x74a55d1f), TOBN(0xe3fbf28f, 0x046f66d8),
+ TOBN(0xa3a72ab4, 0xd4dc4794), TOBN(0x09779f45, 0x5c7c2dd8)},
+ {TOBN(0xd893bdaf, 0xc3d19d8d), TOBN(0xd5a75094, 0x57d6a6df),
+ TOBN(0x8cf8fef9, 0x952e6255), TOBN(0x3da67cfb, 0xda9a8aff)}},
+ {{TOBN(0x4c23f62a, 0x2c160dcd), TOBN(0x34e6c5e3, 0x8f90eaef),
+ TOBN(0x35865519, 0xa9a65d5a), TOBN(0x07c48aae, 0x8fd38a3d)},
+ {TOBN(0xb7e7aeda, 0x50068527), TOBN(0x2c09ef23, 0x1c90936a),
+ TOBN(0x31ecfeb6, 0xe879324c), TOBN(0xa0871f6b, 0xfb0ec938)}},
+ {{TOBN(0xb1f0fb68, 0xd84d835d), TOBN(0xc90caf39, 0x861dc1e6),
+ TOBN(0x12e5b046, 0x7594f8d7), TOBN(0x26897ae2, 0x65012b92)},
+ {TOBN(0xbcf68a08, 0xa4d6755d), TOBN(0x403ee41c, 0x0991fbda),
+ TOBN(0x733e343e, 0x3bbf17e8), TOBN(0xd2c7980d, 0x679b3d65)}},
+ {{TOBN(0x33056232, 0xd2e11305), TOBN(0x966be492, 0xf3c07a6f),
+ TOBN(0x6a8878ff, 0xbb15509d), TOBN(0xff221101, 0x0a9b59a4)},
+ {TOBN(0x6c9f564a, 0xabe30129), TOBN(0xc6f2c940, 0x336e64cf),
+ TOBN(0x0fe75262, 0x8b0c8022), TOBN(0xbe0267e9, 0x6ae8db87)}},
+ {{TOBN(0x22e192f1, 0x93bc042b), TOBN(0xf085b534, 0xb237c458),
+ TOBN(0xa0d192bd, 0x832c4168), TOBN(0x7a76e9e3, 0xbdf6271d)},
+ {TOBN(0x52a882fa, 0xb88911b5), TOBN(0xc85345e4, 0xb4db0eb5),
+ TOBN(0xa3be02a6, 0x81a7c3ff), TOBN(0x51889c8c, 0xf0ec0469)}},
+ {{TOBN(0x9d031369, 0xa5e829e5), TOBN(0xcbb4c6fc, 0x1607aa41),
+ TOBN(0x75ac59a6, 0x241d84c1), TOBN(0xc043f2bf, 0x8829e0ee)},
+ {TOBN(0x82a38f75, 0x8ea5e185), TOBN(0x8bda40b9, 0xd87cbd9f),
+ TOBN(0x9e65e75e, 0x2d8fc601), TOBN(0x3d515f74, 0xa35690b3)}},
+ {{TOBN(0x534acf4f, 0xda79e5ac), TOBN(0x68b83b3a, 0x8630215f),
+ TOBN(0x5c748b2e, 0xd085756e), TOBN(0xb0317258, 0xe5d37cb2)},
+ {TOBN(0x6735841a, 0xc5ccc2c4), TOBN(0x7d7dc96b, 0x3d9d5069),
+ TOBN(0xa147e410, 0xfd1754bd), TOBN(0x65296e94, 0xd399ddd5)}},
+ {{TOBN(0xf6b5b2d0, 0xbc8fa5bc), TOBN(0x8a5ead67, 0x500c277b),
+ TOBN(0x214625e6, 0xdfa08a5d), TOBN(0x51fdfedc, 0x959cf047)},
+ {TOBN(0x6bc9430b, 0x289fca32), TOBN(0xe36ff0cf, 0x9d9bdc3f),
+ TOBN(0x2fe187cb, 0x58ea0ede), TOBN(0xed66af20, 0x5a900b3f)}},
+ {{TOBN(0x00e0968b, 0x5fa9f4d6), TOBN(0x2d4066ce, 0x37a362e7),
+ TOBN(0xa99a9748, 0xbd07e772), TOBN(0x710989c0, 0x06a4f1d0)},
+ {TOBN(0xd5dedf35, 0xce40cbd8), TOBN(0xab55c5f0, 0x1743293d),
+ TOBN(0x766f1144, 0x8aa24e2c), TOBN(0x94d874f8, 0x605fbcb4)}},
+ {{TOBN(0xa365f0e8, 0xa518001b), TOBN(0xee605eb6, 0x9d04ef0f),
+ TOBN(0x5a3915cd, 0xba8d4d25), TOBN(0x44c0e1b8, 0xb5113472)},
+ {TOBN(0xcbb024e8, 0x8b6740dc), TOBN(0x89087a53, 0xee1d4f0c),
+ TOBN(0xa88fa05c, 0x1fc4e372), TOBN(0x8bf395cb, 0xaf8b3af2)}},
+ {{TOBN(0x1e71c9a1, 0xdeb8568b), TOBN(0xa35daea0, 0x80fb3d32),
+ TOBN(0xe8b6f266, 0x2cf8fb81), TOBN(0x6d51afe8, 0x9490696a)},
+ {TOBN(0x81beac6e, 0x51803a19), TOBN(0xe3d24b7f, 0x86219080),
+ TOBN(0x727cfd9d, 0xdf6f463c), TOBN(0x8c6865ca, 0x72284ee8)}},
+ {{TOBN(0x32c88b7d, 0xb743f4ef), TOBN(0x3793909b, 0xe7d11dce),
+ TOBN(0xd398f922, 0x2ff2ebe8), TOBN(0x2c70ca44, 0xe5e49796)},
+ {TOBN(0xdf4d9929, 0xcb1131b1), TOBN(0x7826f298, 0x25888e79),
+ TOBN(0x4d3a112c, 0xf1d8740a), TOBN(0x00384cb6, 0x270afa8b)}},
+ {{TOBN(0xcb64125b, 0x3ab48095), TOBN(0x3451c256, 0x62d05106),
+ TOBN(0xd73d577d, 0xa4955845), TOBN(0x39570c16, 0xbf9f4433)},
+ {TOBN(0xd7dfaad3, 0xadecf263), TOBN(0xf1c3d8d1, 0xdc76e102),
+ TOBN(0x5e774a58, 0x54c6a836), TOBN(0xdad4b672, 0x3e92d47b)}},
+ {{TOBN(0xbe7e990f, 0xf0d796a0), TOBN(0x5fc62478, 0xdf0e8b02),
+ TOBN(0x8aae8bf4, 0x030c00ad), TOBN(0x3d2db93b, 0x9004ba0f)},
+ {TOBN(0xe48c8a79, 0xd85d5ddc), TOBN(0xe907caa7, 0x6bb07f34),
+ TOBN(0x58db343a, 0xa39eaed5), TOBN(0x0ea6e007, 0xadaf5724)}},
+ {{TOBN(0xe00df169, 0xd23233f3), TOBN(0x3e322796, 0x77cb637f),
+ TOBN(0x1f897c0e, 0x1da0cf6c), TOBN(0xa651f5d8, 0x31d6bbdd)},
+ {TOBN(0xdd61af19, 0x1a230c76), TOBN(0xbd527272, 0xcdaa5e4a),
+ TOBN(0xca753636, 0xd0abcd7e), TOBN(0x78bdd37c, 0x370bd8dc)}},
+ {{TOBN(0xc23916c2, 0x17cd93fe), TOBN(0x65b97a4d, 0xdadce6e2),
+ TOBN(0xe04ed4eb, 0x174e42f8), TOBN(0x1491ccaa, 0xbb21480a)},
+ {TOBN(0x145a8280, 0x23196332), TOBN(0x3c3862d7, 0x587b479a),
+ TOBN(0x9f4a88a3, 0x01dcd0ed), TOBN(0x4da2b7ef, 0x3ea12f1f)}},
+ {{TOBN(0xf8e7ae33, 0xb126e48e), TOBN(0x404a0b32, 0xf494e237),
+ TOBN(0x9beac474, 0xc55acadb), TOBN(0x4ee5cf3b, 0xcbec9fd9)},
+ {TOBN(0x336b33b9, 0x7df3c8c3), TOBN(0xbd905fe3, 0xb76808fd),
+ TOBN(0x8f436981, 0xaa45c16a), TOBN(0x255c5bfa, 0x3dd27b62)}},
+ {{TOBN(0x71965cbf, 0xc3dd9b4d), TOBN(0xce23edbf, 0xfc068a87),
+ TOBN(0xb78d4725, 0x745b029b), TOBN(0x74610713, 0xcefdd9bd)},
+ {TOBN(0x7116f75f, 0x1266bf52), TOBN(0x02046722, 0x18e49bb6),
+ TOBN(0xdf43df9f, 0x3d6f19e3), TOBN(0xef1bc7d0, 0xe685cb2f)}},
+ {{TOBN(0xcddb27c1, 0x7078c432), TOBN(0xe1961b9c, 0xb77fedb7),
+ TOBN(0x1edc2f5c, 0xc2290570), TOBN(0x2c3fefca, 0x19cbd886)},
+ {TOBN(0xcf880a36, 0xc2af389a), TOBN(0x96c610fd, 0xbda71cea),
+ TOBN(0xf03977a9, 0x32aa8463), TOBN(0x8eb7763f, 0x8586d90a)}},
+ {{TOBN(0x3f342454, 0x2a296e77), TOBN(0xc8718683, 0x42837a35),
+ TOBN(0x7dc71090, 0x6a09c731), TOBN(0x54778ffb, 0x51b816db)},
+ {TOBN(0x6b33bfec, 0xaf06defd), TOBN(0xfe3c105f, 0x8592b70b),
+ TOBN(0xf937fda4, 0x61da6114), TOBN(0x3c13e651, 0x4c266ad7)}},
+ {{TOBN(0xe363a829, 0x855938e8), TOBN(0x2eeb5d9e, 0x9de54b72),
+ TOBN(0xbeb93b0e, 0x20ccfab9), TOBN(0x3dffbb5f, 0x25e61a25)},
+ {TOBN(0x7f655e43, 0x1acc093d), TOBN(0x0cb6cc3d, 0x3964ce61),
+ TOBN(0x6ab283a1, 0xe5e9b460), TOBN(0x55d787c5, 0xa1c7e72d)}},
+ {{TOBN(0x4d2efd47, 0xdeadbf02), TOBN(0x11e80219, 0xac459068),
+ TOBN(0x810c7626, 0x71f311f0), TOBN(0xfa17ef8d, 0x4ab6ef53)},
+ {TOBN(0xaf47fd25, 0x93e43bff), TOBN(0x5cb5ff3f, 0x0be40632),
+ TOBN(0x54687106, 0x8ee61da3), TOBN(0x7764196e, 0xb08afd0f)}},
+ {{TOBN(0x831ab3ed, 0xf0290a8f), TOBN(0xcae81966, 0xcb47c387),
+ TOBN(0xaad7dece, 0x184efb4f), TOBN(0xdcfc53b3, 0x4749110e)},
+ {TOBN(0x6698f23c, 0x4cb632f9), TOBN(0xc42a1ad6, 0xb91f8067),
+ TOBN(0xb116a81d, 0x6284180a), TOBN(0xebedf5f8, 0xe901326f)}},
+ {{TOBN(0xf2274c9f, 0x97e3e044), TOBN(0x42018520, 0x11d09fc9),
+ TOBN(0x56a65f17, 0xd18e6e23), TOBN(0x2ea61e2a, 0x352b683c)},
+ {TOBN(0x27d291bc, 0x575eaa94), TOBN(0x9e7bc721, 0xb8ff522d),
+ TOBN(0x5f7268bf, 0xa7f04d6f), TOBN(0x5868c73f, 0xaba41748)}},
+ {{TOBN(0x9f85c2db, 0x7be0eead), TOBN(0x511e7842, 0xff719135),
+ TOBN(0x5a06b1e9, 0xc5ea90d7), TOBN(0x0c19e283, 0x26fab631)},
+ {TOBN(0x8af8f0cf, 0xe9206c55), TOBN(0x89389cb4, 0x3553c06a),
+ TOBN(0x39dbed97, 0xf65f8004), TOBN(0x0621b037, 0xc508991d)}},
+ {{TOBN(0x1c52e635, 0x96e78cc4), TOBN(0x5385c8b2, 0x0c06b4a8),
+ TOBN(0xd84ddfdb, 0xb0e87d03), TOBN(0xc49dfb66, 0x934bafad)},
+ {TOBN(0x7071e170, 0x59f70772), TOBN(0x3a073a84, 0x3a1db56b),
+ TOBN(0x03494903, 0x3b8af190), TOBN(0x7d882de3, 0xd32920f0)}},
+ {{TOBN(0x91633f0a, 0xb2cf8940), TOBN(0x72b0b178, 0x6f948f51),
+ TOBN(0x2d28dc30, 0x782653c8), TOBN(0x88829849, 0xdb903a05)},
+ {TOBN(0xb8095d0c, 0x6a19d2bb), TOBN(0x4b9e7f0c, 0x86f782cb),
+ TOBN(0x7af73988, 0x2d907064), TOBN(0xd12be0fe, 0x8b32643c)}},
+ {{TOBN(0x358ed23d, 0x0e165dc3), TOBN(0x3d47ce62, 0x4e2378ce),
+ TOBN(0x7e2bb0b9, 0xfeb8a087), TOBN(0x3246e8ae, 0xe29e10b9)},
+ {TOBN(0x459f4ec7, 0x03ce2b4d), TOBN(0xe9b4ca1b, 0xbbc077cf),
+ TOBN(0x2613b4f2, 0x0e9940c1), TOBN(0xfc598bb9, 0x047d1eb1)}},
+ {{TOBN(0x9744c62b, 0x45036099), TOBN(0xa9dee742, 0x167c65d8),
+ TOBN(0x0c511525, 0xdabe1943), TOBN(0xda110554, 0x93c6c624)},
+ {TOBN(0xae00a52c, 0x651a3be2), TOBN(0xcda5111d, 0x884449a6),
+ TOBN(0x063c06f4, 0xff33bed1), TOBN(0x73baaf9a, 0x0d3d76b4)}},
+ {{TOBN(0x52fb0c9d, 0x7fc63668), TOBN(0x6886c9dd, 0x0c039cde),
+ TOBN(0x602bd599, 0x55b22351), TOBN(0xb00cab02, 0x360c7c13)},
+ {TOBN(0x8cb616bc, 0x81b69442), TOBN(0x41486700, 0xb55c3cee),
+ TOBN(0x71093281, 0xf49ba278), TOBN(0xad956d9c, 0x64a50710)}},
+ {{TOBN(0x9561f28b, 0x638a7e81), TOBN(0x54155cdf, 0x5980ddc3),
+ TOBN(0xb2db4a96, 0xd26f247a), TOBN(0x9d774e4e, 0x4787d100)},
+ {TOBN(0x1a9e6e2e, 0x078637d2), TOBN(0x1c363e2d, 0x5e0ae06a),
+ TOBN(0x7493483e, 0xe9cfa354), TOBN(0x76843cb3, 0x7f74b98d)}},
+ {{TOBN(0xbaca6591, 0xd4b66947), TOBN(0xb452ce98, 0x04460a8c),
+ TOBN(0x6830d246, 0x43768f55), TOBN(0xf4197ed8, 0x7dff12df)},
+ {TOBN(0x6521b472, 0x400dd0f7), TOBN(0x59f5ca8f, 0x4b1e7093),
+ TOBN(0x6feff11b, 0x080338ae), TOBN(0x0ada31f6, 0xa29ca3c6)}},
+ {{TOBN(0x24794eb6, 0x94a2c215), TOBN(0xd83a43ab, 0x05a57ab4),
+ TOBN(0x264a543a, 0x2a6f89fe), TOBN(0x2c2a3868, 0xdd5ec7c2)},
+ {TOBN(0xd3373940, 0x8439d9b2), TOBN(0x715ea672, 0x0acd1f11),
+ TOBN(0x42c1d235, 0xe7e6cc19), TOBN(0x81ce6e96, 0xb990585c)}},
+ {{TOBN(0x04e5dfe0, 0xd809c7bd), TOBN(0xd7b2580c, 0x8f1050ab),
+ TOBN(0x6d91ad78, 0xd8a4176f), TOBN(0x0af556ee, 0x4e2e897c)},
+ {TOBN(0x162a8b73, 0x921de0ac), TOBN(0x52ac9c22, 0x7ea78400),
+ TOBN(0xee2a4eea, 0xefce2174), TOBN(0xbe61844e, 0x6d637f79)}},
+ {{TOBN(0x0491f1bc, 0x789a283b), TOBN(0x72d3ac3d, 0x880836f4),
+ TOBN(0xaa1c5ea3, 0x88e5402d), TOBN(0x1b192421, 0xd5cc473d)},
+ {TOBN(0x5c0b9998, 0x9dc84cac), TOBN(0xb0a8482d, 0x9c6e75b8),
+ TOBN(0x639961d0, 0x3a191ce2), TOBN(0xda3bc865, 0x6d837930)}},
+ {{TOBN(0xca990653, 0x056e6f8f), TOBN(0x84861c41, 0x64d133a7),
+ TOBN(0x8b403276, 0x746abe40), TOBN(0xb7b4d51a, 0xebf8e303)},
+ {TOBN(0x05b43211, 0x220a255d), TOBN(0xc997152c, 0x02419e6e),
+ TOBN(0x76ff47b6, 0x630c2fea), TOBN(0x50518677, 0x281fdade)}},
+ {{TOBN(0x3283b8ba, 0xcf902b0b), TOBN(0x8d4b4eb5, 0x37db303b),
+ TOBN(0xcc89f42d, 0x755011bc), TOBN(0xb43d74bb, 0xdd09d19b)},
+ {TOBN(0x65746bc9, 0x8adba350), TOBN(0x364eaf8c, 0xb51c1927),
+ TOBN(0x13c76596, 0x10ad72ec), TOBN(0x30045121, 0xf8d40c20)}},
+ {{TOBN(0x6d2d99b7, 0xea7b979b), TOBN(0xcd78cd74, 0xe6fb3bcd),
+ TOBN(0x11e45a9e, 0x86cffbfe), TOBN(0x78a61cf4, 0x637024f6)},
+ {TOBN(0xd06bc872, 0x3d502295), TOBN(0xf1376854, 0x458cb288),
+ TOBN(0xb9db26a1, 0x342f8586), TOBN(0xf33effcf, 0x4beee09e)}},
+ {{TOBN(0xd7e0c4cd, 0xb30cfb3a), TOBN(0x6d09b8c1, 0x6c9db4c8),
+ TOBN(0x40ba1a42, 0x07c8d9df), TOBN(0x6fd495f7, 0x1c52c66d)},
+ {TOBN(0xfb0e169f, 0x275264da), TOBN(0x80c2b746, 0xe57d8362),
+ TOBN(0xedd987f7, 0x49ad7222), TOBN(0xfdc229af, 0x4398ec7b)}}},
+ {{{TOBN(0xb0d1ed84, 0x52666a58), TOBN(0x4bcb6e00, 0xe6a9c3c2),
+ TOBN(0x3c57411c, 0x26906408), TOBN(0xcfc20755, 0x13556400)},
+ {TOBN(0xa08b1c50, 0x5294dba3), TOBN(0xa30ba286, 0x8b7dd31e),
+ TOBN(0xd70ba90e, 0x991eca74), TOBN(0x094e142c, 0xe762c2b9)}},
+ {{TOBN(0xb81d783e, 0x979f3925), TOBN(0x1efd130a, 0xaf4c89a7),
+ TOBN(0x525c2144, 0xfd1bf7fa), TOBN(0x4b296904, 0x1b265a9e)},
+ {TOBN(0xed8e9634, 0xb9db65b6), TOBN(0x35c82e32, 0x03599d8a),
+ TOBN(0xdaa7a54f, 0x403563f3), TOBN(0x9df088ad, 0x022c38ab)}},
+ {{TOBN(0xe5cfb066, 0xbb3fd30a), TOBN(0x429169da, 0xeff0354e),
+ TOBN(0x809cf852, 0x3524e36c), TOBN(0x136f4fb3, 0x0155be1d)},
+ {TOBN(0x4826af01, 0x1fbba712), TOBN(0x6ef0f0b4, 0x506ba1a1),
+ TOBN(0xd9928b31, 0x77aea73e), TOBN(0xe2bf6af2, 0x5eaa244e)}},
+ {{TOBN(0x8d084f12, 0x4237b64b), TOBN(0x688ebe99, 0xe3ecfd07),
+ TOBN(0x57b8a70c, 0xf6845dd8), TOBN(0x808fc59c, 0x5da4a325)},
+ {TOBN(0xa9032b2b, 0xa3585862), TOBN(0xb66825d5, 0xedf29386),
+ TOBN(0xb5a5a8db, 0x431ec29b), TOBN(0xbb143a98, 0x3a1e8dc8)}},
+ {{TOBN(0x35ee94ce, 0x12ae381b), TOBN(0x3a7f176c, 0x86ccda90),
+ TOBN(0xc63a657e, 0x4606eaca), TOBN(0x9ae5a380, 0x43cd04df)},
+ {TOBN(0x9bec8d15, 0xed251b46), TOBN(0x1f5d6d30, 0xcaca5e64),
+ TOBN(0x347b3b35, 0x9ff20f07), TOBN(0x4d65f034, 0xf7e4b286)}},
+ {{TOBN(0x9e93ba24, 0xf111661e), TOBN(0xedced484, 0xb105eb04),
+ TOBN(0x96dc9ba1, 0xf424b578), TOBN(0xbf8f66b7, 0xe83e9069)},
+ {TOBN(0x872d4df4, 0xd7ed8216), TOBN(0xbf07f377, 0x8e2cbecf),
+ TOBN(0x4281d899, 0x98e73754), TOBN(0xfec85fbb, 0x8aab8708)}},
+ {{TOBN(0x9a3c0dee, 0xa5ba5b0b), TOBN(0xe6a116ce, 0x42d05299),
+ TOBN(0xae9775fe, 0xe9b02d42), TOBN(0x72b05200, 0xa1545cb6)},
+ {TOBN(0xbc506f7d, 0x31a3b4ea), TOBN(0xe5893078, 0x8bbd9b32),
+ TOBN(0xc8bc5f37, 0xe4b12a97), TOBN(0x6b000c06, 0x4a73b671)}},
+ {{TOBN(0x13b5bf22, 0x765fa7d0), TOBN(0x59805bf0, 0x1d6a5370),
+ TOBN(0x67a5e29d, 0x4280db98), TOBN(0x4f53916f, 0x776b1ce3)},
+ {TOBN(0x714ff61f, 0x33ddf626), TOBN(0x4206238e, 0xa085d103),
+ TOBN(0x1c50d4b7, 0xe5809ee3), TOBN(0x999f450d, 0x85f8eb1d)}},
+ {{TOBN(0x658a6051, 0xe4c79e9b), TOBN(0x1394cb73, 0xc66a9fea),
+ TOBN(0x27f31ed5, 0xc6be7b23), TOBN(0xf4c88f36, 0x5aa6f8fe)},
+ {TOBN(0x0fb0721f, 0x4aaa499e), TOBN(0x68b3a7d5, 0xe3fb2a6b),
+ TOBN(0xa788097d, 0x3a92851d), TOBN(0x060e7f8a, 0xe96f4913)}},
+ {{TOBN(0x82eebe73, 0x1a3a93bc), TOBN(0x42bbf465, 0xa21adc1a),
+ TOBN(0xc10b6fa4, 0xef030efd), TOBN(0x247aa4c7, 0x87b097bb)},
+ {TOBN(0x8b8dc632, 0xf60c77da), TOBN(0x6ffbc26a, 0xc223523e),
+ TOBN(0xa4f6ff11, 0x344579cf), TOBN(0x5825653c, 0x980250f6)}},
+ {{TOBN(0xb2dd097e, 0xbc1aa2b9), TOBN(0x07889393, 0x37a0333a),
+ TOBN(0x1cf55e71, 0x37a0db38), TOBN(0x2648487f, 0x792c1613)},
+ {TOBN(0xdad01336, 0x3fcef261), TOBN(0x6239c81d, 0x0eabf129),
+ TOBN(0x8ee761de, 0x9d276be2), TOBN(0x406a7a34, 0x1eda6ad3)}},
+ {{TOBN(0x4bf367ba, 0x4a493b31), TOBN(0x54f20a52, 0x9bf7f026),
+ TOBN(0xb696e062, 0x9795914b), TOBN(0xcddab96d, 0x8bf236ac)},
+ {TOBN(0x4ff2c70a, 0xed25ea13), TOBN(0xfa1d09eb, 0x81cbbbe7),
+ TOBN(0x88fc8c87, 0x468544c5), TOBN(0x847a670d, 0x696b3317)}},
+ {{TOBN(0xf133421e, 0x64bcb626), TOBN(0xaea638c8, 0x26dee0b5),
+ TOBN(0xd6e7680b, 0xb310346c), TOBN(0xe06f4097, 0xd5d4ced3)},
+ {TOBN(0x09961452, 0x7512a30b), TOBN(0xf3d867fd, 0xe589a59a),
+ TOBN(0x2e73254f, 0x52d0c180), TOBN(0x9063d8a3, 0x333c74ac)}},
+ {{TOBN(0xeda6c595, 0xd314e7bc), TOBN(0x2ee7464b, 0x467899ed),
+ TOBN(0x1cef423c, 0x0a1ed5d3), TOBN(0x217e76ea, 0x69cc7613)},
+ {TOBN(0x27ccce1f, 0xe7cda917), TOBN(0x12d8016b, 0x8a893f16),
+ TOBN(0xbcd6de84, 0x9fc74f6b), TOBN(0xfa5817e2, 0xf3144e61)}},
+ {{TOBN(0x1f354164, 0x0821ee4c), TOBN(0x1583eab4, 0x0bc61992),
+ TOBN(0x7490caf6, 0x1d72879f), TOBN(0x998ad9f3, 0xf76ae7b2)},
+ {TOBN(0x1e181950, 0xa41157f7), TOBN(0xa9d7e1e6, 0xe8da3a7e),
+ TOBN(0x963784eb, 0x8426b95f), TOBN(0x0ee4ed6e, 0x542e2a10)}},
+ {{TOBN(0xb79d4cc5, 0xac751e7b), TOBN(0x93f96472, 0xfd4211bd),
+ TOBN(0x8c72d3d2, 0xc8de4fc6), TOBN(0x7b69cbf5, 0xdf44f064)},
+ {TOBN(0x3da90ca2, 0xf4bf94e1), TOBN(0x1a5325f8, 0xf12894e2),
+ TOBN(0x0a437f6c, 0x7917d60b), TOBN(0x9be70486, 0x96c9cb5d)}},
+ {{TOBN(0xb4d880bf, 0xe1dc5c05), TOBN(0xd738adda, 0xeebeeb57),
+ TOBN(0x6f0119d3, 0xdf0fe6a3), TOBN(0x5c686e55, 0x66eaaf5a)},
+ {TOBN(0x9cb10b50, 0xdfd0b7ec), TOBN(0xbdd0264b, 0x6a497c21),
+ TOBN(0xfc093514, 0x8c546c96), TOBN(0x58a947fa, 0x79dbf42a)}},
+ {{TOBN(0xc0b48d4e, 0x49ccd6d7), TOBN(0xff8fb02c, 0x88bd5580),
+ TOBN(0xc75235e9, 0x07d473b2), TOBN(0x4fab1ac5, 0xa2188af3)},
+ {TOBN(0x030fa3bc, 0x97576ec0), TOBN(0xe8c946e8, 0x0b7e7d2f),
+ TOBN(0x40a5c9cc, 0x70305600), TOBN(0x6d8260a9, 0xc8b013b4)}},
+ {{TOBN(0x0368304f, 0x70bba85c), TOBN(0xad090da1, 0xa4a0d311),
+ TOBN(0x7170e870, 0x2415eec1), TOBN(0xbfba35fe, 0x8461ea47)},
+ {TOBN(0x6279019a, 0xc1e91938), TOBN(0xa47638f3, 0x1afc415f),
+ TOBN(0x36c65cbb, 0xbcba0e0f), TOBN(0x02160efb, 0x034e2c48)}},
+ {{TOBN(0xe6c51073, 0x615cd9e4), TOBN(0x498ec047, 0xf1243c06),
+ TOBN(0x3e5a8809, 0xb17b3d8c), TOBN(0x5cd99e61, 0x0cc565f1)},
+ {TOBN(0x81e312df, 0x7851dafe), TOBN(0xf156f5ba, 0xa79061e2),
+ TOBN(0x80d62b71, 0x880c590e), TOBN(0xbec9746f, 0x0a39faa1)}},
+ {{TOBN(0x1d98a9c1, 0xc8ed1f7a), TOBN(0x09e43bb5, 0xa81d5ff2),
+ TOBN(0xd5f00f68, 0x0da0794a), TOBN(0x412050d9, 0x661aa836)},
+ {TOBN(0xa89f7c4e, 0x90747e40), TOBN(0x6dc05ebb, 0xb62a3686),
+ TOBN(0xdf4de847, 0x308e3353), TOBN(0x53868fbb, 0x9fb53bb9)}},
+ {{TOBN(0x2b09d2c3, 0xcfdcf7dd), TOBN(0x41a9fce3, 0x723fcab4),
+ TOBN(0x73d905f7, 0x07f57ca3), TOBN(0x080f9fb1, 0xac8e1555)},
+ {TOBN(0x7c088e84, 0x9ba7a531), TOBN(0x07d35586, 0xed9a147f),
+ TOBN(0x602846ab, 0xaf48c336), TOBN(0x7320fd32, 0x0ccf0e79)}},
+ {{TOBN(0xaa780798, 0xb18bd1ff), TOBN(0x52c2e300, 0xafdd2905),
+ TOBN(0xf27ea3d6, 0x434267cd), TOBN(0x8b96d16d, 0x15605b5f)},
+ {TOBN(0x7bb31049, 0x4b45706b), TOBN(0xe7f58b8e, 0x743d25f8),
+ TOBN(0xe9b5e45b, 0x87f30076), TOBN(0xd19448d6, 0x5d053d5a)}},
+ {{TOBN(0x1ecc8cb9, 0xd3210a04), TOBN(0x6bc7d463, 0xdafb5269),
+ TOBN(0x3e59b10a, 0x67c3489f), TOBN(0x1769788c, 0x65641e1b)},
+ {TOBN(0x8a53b82d, 0xbd6cb838), TOBN(0x7066d6e6, 0x236d5f22),
+ TOBN(0x03aa1c61, 0x6908536e), TOBN(0xc971da0d, 0x66ae9809)}},
+ {{TOBN(0x01b3a86b, 0xc49a2fac), TOBN(0x3b8420c0, 0x3092e77a),
+ TOBN(0x02057300, 0x7d6fb556), TOBN(0x6941b2a1, 0xbff40a87)},
+ {TOBN(0x140b6308, 0x0658ff2a), TOBN(0x87804363, 0x3424ab36),
+ TOBN(0x0253bd51, 0x5751e299), TOBN(0xc75bcd76, 0x449c3e3a)}},
+ {{TOBN(0x92eb4090, 0x7f8f875d), TOBN(0x9c9d754e, 0x56c26bbf),
+ TOBN(0x158cea61, 0x8110bbe7), TOBN(0x62a6b802, 0x745f91ea)},
+ {TOBN(0xa79c41aa, 0xc6e7394b), TOBN(0x445b6a83, 0xad57ef10),
+ TOBN(0x0c5277eb, 0x6ea6f40c), TOBN(0x319fe96b, 0x88633365)}},
+ {{TOBN(0x0b0fc61f, 0x385f63cb), TOBN(0x41250c84, 0x22bdd127),
+ TOBN(0x67d153f1, 0x09e942c2), TOBN(0x60920d08, 0xc021ad5d)},
+ {TOBN(0x229f5746, 0x724d81a5), TOBN(0xb7ffb892, 0x5bba3299),
+ TOBN(0x518c51a1, 0xde413032), TOBN(0x2a9bfe77, 0x3c2fd94c)}},
+ {{TOBN(0xcbcde239, 0x3191f4fd), TOBN(0x43093e16, 0xd3d6ada1),
+ TOBN(0x184579f3, 0x58769606), TOBN(0x2c94a8b3, 0xd236625c)},
+ {TOBN(0x6922b9c0, 0x5c437d8e), TOBN(0x3d4ae423, 0xd8d9f3c8),
+ TOBN(0xf72c31c1, 0x2e7090a2), TOBN(0x4ac3f5f3, 0xd76a55bd)}},
+ {{TOBN(0x342508fc, 0x6b6af991), TOBN(0x0d527100, 0x1b5cebbd),
+ TOBN(0xb84740d0, 0xdd440dd7), TOBN(0x748ef841, 0x780162fd)},
+ {TOBN(0xa8dbfe0e, 0xdfc6fafb), TOBN(0xeadfdf05, 0xf7300f27),
+ TOBN(0x7d06555f, 0xfeba4ec9), TOBN(0x12c56f83, 0x9e25fa97)}},
+ {{TOBN(0x77f84203, 0xd39b8c34), TOBN(0xed8b1be6, 0x3125eddb),
+ TOBN(0x5bbf2441, 0xf6e39dc5), TOBN(0xb00f6ee6, 0x6a5d678a)},
+ {TOBN(0xba456ecf, 0x57d0ea99), TOBN(0xdcae0f58, 0x17e06c43),
+ TOBN(0x01643de4, 0x0f5b4baa), TOBN(0x2c324341, 0xd161b9be)}},
+ {{TOBN(0x80177f55, 0xe126d468), TOBN(0xed325f1f, 0x76748e09),
+ TOBN(0x6116004a, 0xcfa9bdc2), TOBN(0x2d8607e6, 0x3a9fb468)},
+ {TOBN(0x0e573e27, 0x6009d660), TOBN(0x3a525d2e, 0x8d10c5a1),
+ TOBN(0xd26cb45c, 0x3b9009a0), TOBN(0xb6b0cdc0, 0xde9d7448)}},
+ {{TOBN(0x949c9976, 0xe1337c26), TOBN(0x6faadebd, 0xd73d68e5),
+ TOBN(0x9e158614, 0xf1b768d9), TOBN(0x22dfa557, 0x9cc4f069)},
+ {TOBN(0xccd6da17, 0xbe93c6d6), TOBN(0x24866c61, 0xa504f5b9),
+ TOBN(0x2121353c, 0x8d694da1), TOBN(0x1c6ca580, 0x0140b8c6)}},
+ {{TOBN(0xc245ad8c, 0xe964021e), TOBN(0xb83bffba, 0x032b82b3),
+ TOBN(0xfaa220c6, 0x47ef9898), TOBN(0x7e8d3ac6, 0x982c948a)},
+ {TOBN(0x1faa2091, 0xbc2d124a), TOBN(0xbd54c3dd, 0x05b15ff4),
+ TOBN(0x386bf3ab, 0xc87c6fb7), TOBN(0xfb2b0563, 0xfdeb6f66)}},
+ {{TOBN(0x4e77c557, 0x5b45afb4), TOBN(0xe9ded649, 0xefb8912d),
+ TOBN(0x7ec9bbf5, 0x42f6e557), TOBN(0x2570dfff, 0x62671f00)},
+ {TOBN(0x2b3bfb78, 0x88e084bd), TOBN(0xa024b238, 0xf37fe5b4),
+ TOBN(0x44e7dc04, 0x95649aee), TOBN(0x498ca255, 0x5e7ec1d8)}},
+ {{TOBN(0x3bc766ea, 0xaaa07e86), TOBN(0x0db6facb, 0xf3608586),
+ TOBN(0xbadd2549, 0xbdc259c8), TOBN(0x95af3c6e, 0x041c649f)},
+ {TOBN(0xb36a928c, 0x02e30afb), TOBN(0x9b5356ad, 0x008a88b8),
+ TOBN(0x4b67a5f1, 0xcf1d9e9d), TOBN(0xc6542e47, 0xa5d8d8ce)}},
+ {{TOBN(0x73061fe8, 0x7adfb6cc), TOBN(0xcc826fd3, 0x98678141),
+ TOBN(0x00e758b1, 0x3c80515a), TOBN(0x6afe3247, 0x41485083)},
+ {TOBN(0x0fcb08b9, 0xb6ae8a75), TOBN(0xb8cf388d, 0x4acf51e1),
+ TOBN(0x344a5560, 0x6961b9d6), TOBN(0x1a6778b8, 0x6a97fd0c)}},
+ {{TOBN(0xd840fdc1, 0xecc4c7e3), TOBN(0xde9fe47d, 0x16db68cc),
+ TOBN(0xe95f89de, 0xa3e216aa), TOBN(0x84f1a6a4, 0x9594a8be)},
+ {TOBN(0x7ddc7d72, 0x5a7b162b), TOBN(0xc5cfda19, 0xadc817a3),
+ TOBN(0x80a5d350, 0x78b58d46), TOBN(0x93365b13, 0x82978f19)}},
+ {{TOBN(0x2e44d225, 0x26a1fc90), TOBN(0x0d6d10d2, 0x4d70705d),
+ TOBN(0xd94b6b10, 0xd70c45f4), TOBN(0x0f201022, 0xb216c079)},
+ {TOBN(0xcec966c5, 0x658fde41), TOBN(0xa8d2bc7d, 0x7e27601d),
+ TOBN(0xbfcce3e1, 0xff230be7), TOBN(0x3394ff6b, 0x0033ffb5)}},
+ {{TOBN(0xd890c509, 0x8132c9af), TOBN(0xaac4b0eb, 0x361e7868),
+ TOBN(0x5194ded3, 0xe82d15aa), TOBN(0x4550bd2e, 0x23ae6b7d)},
+ {TOBN(0x3fda318e, 0xea5399d4), TOBN(0xd989bffa, 0x91638b80),
+ TOBN(0x5ea124d0, 0xa14aa12d), TOBN(0x1fb1b899, 0x3667b944)}},
+ {{TOBN(0x95ec7969, 0x44c44d6a), TOBN(0x91df144a, 0x57e86137),
+ TOBN(0x915fd620, 0x73adac44), TOBN(0x8f01732d, 0x59a83801)},
+ {TOBN(0xec579d25, 0x3aa0a633), TOBN(0x06de5e7c, 0xc9d6d59c),
+ TOBN(0xc132f958, 0xb1ef8010), TOBN(0x29476f96, 0xe65c1a02)}},
+ {{TOBN(0x336a77c0, 0xd34c3565), TOBN(0xef1105b2, 0x1b9f1e9e),
+ TOBN(0x63e6d08b, 0xf9e08002), TOBN(0x9aff2f21, 0xc613809e)},
+ {TOBN(0xb5754f85, 0x3a80e75d), TOBN(0xde71853e, 0x6bbda681),
+ TOBN(0x86f041df, 0x8197fd7a), TOBN(0x8b332e08, 0x127817fa)}},
+ {{TOBN(0x05d99be8, 0xb9c20cda), TOBN(0x89f7aad5, 0xd5cd0c98),
+ TOBN(0x7ef936fe, 0x5bb94183), TOBN(0x92ca0753, 0xb05cd7f2)},
+ {TOBN(0x9d65db11, 0x74a1e035), TOBN(0x02628cc8, 0x13eaea92),
+ TOBN(0xf2d9e242, 0x49e4fbf2), TOBN(0x94fdfd9b, 0xe384f8b7)}},
+ {{TOBN(0x65f56054, 0x63428c6b), TOBN(0x2f7205b2, 0x90b409a5),
+ TOBN(0xf778bb78, 0xff45ae11), TOBN(0xa13045be, 0xc5ee53b2)},
+ {TOBN(0xe00a14ff, 0x03ef77fe), TOBN(0x689cd59f, 0xffef8bef),
+ TOBN(0x3578f0ed, 0x1e9ade22), TOBN(0xe99f3ec0, 0x6268b6a8)}},
+ {{TOBN(0xa2057d91, 0xea1b3c3e), TOBN(0x2d1a7053, 0xb8823a4a),
+ TOBN(0xabbb336a, 0x2cca451e), TOBN(0xcd2466e3, 0x2218bb5d)},
+ {TOBN(0x3ac1f42f, 0xc8cb762d), TOBN(0x7e312aae, 0x7690211f),
+ TOBN(0xebb9bd73, 0x45d07450), TOBN(0x207c4b82, 0x46c2213f)}},
+ {{TOBN(0x99d425c1, 0x375913ec), TOBN(0x94e45e96, 0x67908220),
+ TOBN(0xc08f3087, 0xcd67dbf6), TOBN(0xa5670fbe, 0xc0887056)},
+ {TOBN(0x6717b64a, 0x66f5b8fc), TOBN(0xd5a56aea, 0x786fec28),
+ TOBN(0xa8c3f55f, 0xc0ff4952), TOBN(0xa77fefae, 0x457ac49b)}},
+ {{TOBN(0x29882d7c, 0x98379d44), TOBN(0xd000bdfb, 0x509edc8a),
+ TOBN(0xc6f95979, 0xe66fe464), TOBN(0x504a6115, 0xfa61bde0)},
+ {TOBN(0x56b3b871, 0xeffea31a), TOBN(0x2d3de26d, 0xf0c21a54),
+ TOBN(0x21dbff31, 0x834753bf), TOBN(0xe67ecf49, 0x69269d86)}},
+ {{TOBN(0x7a176952, 0x151fe690), TOBN(0x03515804, 0x7f2adb5f),
+ TOBN(0xee794b15, 0xd1b62a8d), TOBN(0xf004ceec, 0xaae454e6)},
+ {TOBN(0x0897ea7c, 0xf0386fac), TOBN(0x3b62ff12, 0xd1fca751),
+ TOBN(0x154181df, 0x1b7a04ec), TOBN(0x2008e04a, 0xfb5847ec)}},
+ {{TOBN(0xd147148e, 0x41dbd772), TOBN(0x2b419f73, 0x22942654),
+ TOBN(0x669f30d3, 0xe9c544f7), TOBN(0x52a2c223, 0xc8540149)},
+ {TOBN(0x5da9ee14, 0x634dfb02), TOBN(0x5f074ff0, 0xf47869f3),
+ TOBN(0x74ee878d, 0xa3933acc), TOBN(0xe6510651, 0x4fe35ed1)}},
+ {{TOBN(0xb3eb9482, 0xf1012e7a), TOBN(0x51013cc0, 0xa8a566ae),
+ TOBN(0xdd5e9243, 0x47c00d3b), TOBN(0x7fde089d, 0x946bb0e5)},
+ {TOBN(0x030754fe, 0xc731b4b3), TOBN(0x12a136a4, 0x99fda062),
+ TOBN(0x7c1064b8, 0x5a1a35bc), TOBN(0xbf1f5763, 0x446c84ef)}},
+ {{TOBN(0xed29a56d, 0xa16d4b34), TOBN(0x7fba9d09, 0xdca21c4f),
+ TOBN(0x66d7ac00, 0x6d8de486), TOBN(0x60061987, 0x73a2a5e1)},
+ {TOBN(0x8b400f86, 0x9da28ff0), TOBN(0x3133f708, 0x43c4599c),
+ TOBN(0x9911c9b8, 0xee28cb0d), TOBN(0xcd7e2874, 0x8e0af61d)}},
+ {{TOBN(0x5a85f0f2, 0x72ed91fc), TOBN(0x85214f31, 0x9cd4a373),
+ TOBN(0x881fe5be, 0x1925253c), TOBN(0xd8dc98e0, 0x91e8bc76)},
+ {TOBN(0x7120affe, 0x585cc3a2), TOBN(0x724952ed, 0x735bf97a),
+ TOBN(0x5581e7dc, 0x3eb34581), TOBN(0x5cbff4f2, 0xe52ee57d)}},
+ {{TOBN(0x8d320a0e, 0x87d8cc7b), TOBN(0x9beaa7f3, 0xf1d280d0),
+ TOBN(0x7a0b9571, 0x9beec704), TOBN(0x9126332e, 0x5b7f0057)},
+ {TOBN(0x01fbc1b4, 0x8ed3bd6d), TOBN(0x35bb2c12, 0xd945eb24),
+ TOBN(0x6404694e, 0x9a8ae255), TOBN(0xb6092eec, 0x8d6abfb3)}},
+ {{TOBN(0x4d76143f, 0xcc058865), TOBN(0x7b0a5af2, 0x6e249922),
+ TOBN(0x8aef9440, 0x6a50d353), TOBN(0xe11e4bcc, 0x64f0e07a)},
+ {TOBN(0x4472993a, 0xa14a90fa), TOBN(0x7706e20c, 0xba0c51d4),
+ TOBN(0xf403292f, 0x1532672d), TOBN(0x52573bfa, 0x21829382)}},
+ {{TOBN(0x6a7bb6a9, 0x3b5bdb83), TOBN(0x08da65c0, 0xa4a72318),
+ TOBN(0xc58d22aa, 0x63eb065f), TOBN(0x1717596c, 0x1b15d685)},
+ {TOBN(0x112df0d0, 0xb266d88b), TOBN(0xf688ae97, 0x5941945a),
+ TOBN(0x487386e3, 0x7c292cac), TOBN(0x42f3b50d, 0x57d6985c)}},
+ {{TOBN(0x6da4f998, 0x6a90fc34), TOBN(0xc8f257d3, 0x65ca8a8d),
+ TOBN(0xc2feabca, 0x6951f762), TOBN(0xe1bc81d0, 0x74c323ac)},
+ {TOBN(0x1bc68f67, 0x251a2a12), TOBN(0x10d86587, 0xbe8a70dc),
+ TOBN(0xd648af7f, 0xf0f84d2e), TOBN(0xf0aa9ebc, 0x6a43ac92)}},
+ {{TOBN(0x69e3be04, 0x27596893), TOBN(0xb6bb02a6, 0x45bf452b),
+ TOBN(0x0875c11a, 0xf4c698c8), TOBN(0x6652b5c7, 0xbece3794)},
+ {TOBN(0x7b3755fd, 0x4f5c0499), TOBN(0x6ea16558, 0xb5532b38),
+ TOBN(0xd1c69889, 0xa2e96ef7), TOBN(0x9c773c3a, 0x61ed8f48)}},
+ {{TOBN(0x2b653a40, 0x9b323abc), TOBN(0xe26605e1, 0xf0e1d791),
+ TOBN(0x45d41064, 0x4a87157a), TOBN(0x8f9a78b7, 0xcbbce616)},
+ {TOBN(0xcf1e44aa, 0xc407eddd), TOBN(0x81ddd1d8, 0xa35b964f),
+ TOBN(0x473e339e, 0xfd083999), TOBN(0x6c94bdde, 0x8e796802)}},
+ {{TOBN(0x5a304ada, 0x8545d185), TOBN(0x82ae44ea, 0x738bb8cb),
+ TOBN(0x628a35e3, 0xdf87e10e), TOBN(0xd3624f3d, 0xa15b9fe3)},
+ {TOBN(0xcc44209b, 0x14be4254), TOBN(0x7d0efcbc, 0xbdbc2ea5),
+ TOBN(0x1f603362, 0x04c37bbe), TOBN(0x21f363f5, 0x56a5852c)}},
+ {{TOBN(0xa1503d1c, 0xa8501550), TOBN(0x2251e0e1, 0xd8ab10bb),
+ TOBN(0xde129c96, 0x6961c51c), TOBN(0x1f7246a4, 0x81910f68)},
+ {TOBN(0x2eb744ee, 0x5f2591f2), TOBN(0x3c47d33f, 0x5e627157),
+ TOBN(0x4d6d62c9, 0x22f3bd68), TOBN(0x6120a64b, 0xcb8df856)}},
+ {{TOBN(0x3a9ac6c0, 0x7b5d07df), TOBN(0xa92b9558, 0x7ef39783),
+ TOBN(0xe128a134, 0xab3a9b4f), TOBN(0x41c18807, 0xb1252f05)},
+ {TOBN(0xfc7ed089, 0x80ba9b1c), TOBN(0xac8dc6de, 0xc532a9dd),
+ TOBN(0xbf829cef, 0x55246809), TOBN(0x101b784f, 0x5b4ee80f)}},
+ {{TOBN(0xc09945bb, 0xb6f11603), TOBN(0x57b09dbe, 0x41d2801e),
+ TOBN(0xfba5202f, 0xa97534a8), TOBN(0x7fd8ae5f, 0xc17b9614)},
+ {TOBN(0xa50ba666, 0x78308435), TOBN(0x9572f77c, 0xd3868c4d),
+ TOBN(0x0cef7bfd, 0x2dd7aab0), TOBN(0xe7958e08, 0x2c7c79ff)}},
+ {{TOBN(0x81262e42, 0x25346689), TOBN(0x716da290, 0xb07c7004),
+ TOBN(0x35f911ea, 0xb7950ee3), TOBN(0x6fd72969, 0x261d21b5)},
+ {TOBN(0x52389803, 0x08b640d3), TOBN(0x5b0026ee, 0x887f12a1),
+ TOBN(0x20e21660, 0x742e9311), TOBN(0x0ef6d541, 0x5ff77ff7)}},
+ {{TOBN(0x969127f0, 0xf9c41135), TOBN(0xf21d60c9, 0x68a64993),
+ TOBN(0x656e5d0c, 0xe541875c), TOBN(0xf1e0f84e, 0xa1d3c233)},
+ {TOBN(0x9bcca359, 0x06002d60), TOBN(0xbe2da60c, 0x06191552),
+ TOBN(0x5da8bbae, 0x61181ec3), TOBN(0x9f04b823, 0x65806f19)}},
+ {{TOBN(0xf1604a7d, 0xd4b79bb8), TOBN(0xaee806fb, 0x52c878c8),
+ TOBN(0x34144f11, 0x8d47b8e8), TOBN(0x72edf52b, 0x949f9054)},
+ {TOBN(0xebfca84e, 0x2127015a), TOBN(0x9051d0c0, 0x9cb7cef3),
+ TOBN(0x86e8fe58, 0x296deec8), TOBN(0x33b28188, 0x41010d74)}}},
+ {{{TOBN(0x01079383, 0x171b445f), TOBN(0x9bcf21e3, 0x8131ad4c),
+ TOBN(0x8cdfe205, 0xc93987e8), TOBN(0xe63f4152, 0xc92e8c8f)},
+ {TOBN(0x729462a9, 0x30add43d), TOBN(0x62ebb143, 0xc980f05a),
+ TOBN(0x4f3954e5, 0x3b06e968), TOBN(0xfe1d75ad, 0x242cf6b1)}},
+ {{TOBN(0x5f95c6c7, 0xaf8685c8), TOBN(0xd4c1c8ce, 0x2f8f01aa),
+ TOBN(0xc44bbe32, 0x2574692a), TOBN(0xb8003478, 0xd4a4a068)},
+ {TOBN(0x7c8fc6e5, 0x2eca3cdb), TOBN(0xea1db16b, 0xec04d399),
+ TOBN(0xb05bc82e, 0x8f2bc5cf), TOBN(0x763d517f, 0xf44793d2)}},
+ {{TOBN(0x4451c1b8, 0x08bd98d0), TOBN(0x644b1cd4, 0x6575f240),
+ TOBN(0x6907eb33, 0x7375d270), TOBN(0x56c8bebd, 0xfa2286bd)},
+ {TOBN(0xc713d2ac, 0xc4632b46), TOBN(0x17da427a, 0xafd60242),
+ TOBN(0x313065b7, 0xc95c7546), TOBN(0xf8239898, 0xbf17a3de)}},
+ {{TOBN(0xf3b7963f, 0x4c830320), TOBN(0x842c7aa0, 0x903203e3),
+ TOBN(0xaf22ca0a, 0xe7327afb), TOBN(0x38e13092, 0x967609b6)},
+ {TOBN(0x73b8fb62, 0x757558f1), TOBN(0x3cc3e831, 0xf7eca8c1),
+ TOBN(0xe4174474, 0xf6331627), TOBN(0xa77989ca, 0xc3c40234)}},
+ {{TOBN(0xe5fd17a1, 0x44a081e0), TOBN(0xd797fb7d, 0xb70e296a),
+ TOBN(0x2b472b30, 0x481f719c), TOBN(0x0e632a98, 0xfe6f8c52)},
+ {TOBN(0x89ccd116, 0xc5f0c284), TOBN(0xf51088af, 0x2d987c62),
+ TOBN(0x2a2bccda, 0x4c2de6cf), TOBN(0x810f9efe, 0xf679f0f9)}},
+ {{TOBN(0xb0f394b9, 0x7ffe4b3e), TOBN(0x0b691d21, 0xe5fa5d21),
+ TOBN(0xb0bd7747, 0x9dfbbc75), TOBN(0xd2830fda, 0xfaf78b00)},
+ {TOBN(0xf78c249c, 0x52434f57), TOBN(0x4b1f7545, 0x98096dab),
+ TOBN(0x73bf6f94, 0x8ff8c0b3), TOBN(0x34aef03d, 0x454e134c)}},
+ {{TOBN(0xf8d151f4, 0xb7ac7ec5), TOBN(0xd6ceb95a, 0xe50da7d5),
+ TOBN(0xa1b492b0, 0xdc3a0eb8), TOBN(0x75157b69, 0xb3dd2863)},
+ {TOBN(0xe2c4c74e, 0xc5413d62), TOBN(0xbe329ff7, 0xbc5fc4c7),
+ TOBN(0x835a2aea, 0x60fa9dda), TOBN(0xf117f5ad, 0x7445cb87)}},
+ {{TOBN(0xae8317f4, 0xb0166f7a), TOBN(0xfbd3e3f7, 0xceec74e6),
+ TOBN(0xfdb516ac, 0xe0874bfd), TOBN(0x3d846019, 0xc681f3a3)},
+ {TOBN(0x0b12ee5c, 0x7c1620b0), TOBN(0xba68b4dd, 0x2b63c501),
+ TOBN(0xac03cd32, 0x6668c51e), TOBN(0x2a6279f7, 0x4e0bcb5b)}},
+ {{TOBN(0x17bd69b0, 0x6ae85c10), TOBN(0x72946979, 0x1dfdd3a6),
+ TOBN(0xd9a03268, 0x2c078bec), TOBN(0x41c6a658, 0xbfd68a52)},
+ {TOBN(0xcdea1024, 0x0e023900), TOBN(0xbaeec121, 0xb10d144d),
+ TOBN(0x5a600e74, 0x058ab8dc), TOBN(0x1333af21, 0xbb89ccdd)}},
+ {{TOBN(0xdf25eae0, 0x3aaba1f1), TOBN(0x2cada16e, 0x3b7144cf),
+ TOBN(0x657ee27d, 0x71ab98bc), TOBN(0x99088b4c, 0x7a6fc96e)},
+ {TOBN(0x05d5c0a0, 0x3549dbd4), TOBN(0x42cbdf8f, 0xf158c3ac),
+ TOBN(0x3fb6b3b0, 0x87edd685), TOBN(0x22071cf6, 0x86f064d0)}},
+ {{TOBN(0xd2d6721f, 0xff2811e5), TOBN(0xdb81b703, 0xfe7fae8c),
+ TOBN(0x3cfb74ef, 0xd3f1f7bb), TOBN(0x0cdbcd76, 0x16cdeb5d)},
+ {TOBN(0x4f39642a, 0x566a808c), TOBN(0x02b74454, 0x340064d6),
+ TOBN(0xfabbadca, 0x0528fa6f), TOBN(0xe4c3074c, 0xd3fc0bb6)}},
+ {{TOBN(0xb32cb8b0, 0xb796d219), TOBN(0xc3e95f4f, 0x34741dd9),
+ TOBN(0x87212125, 0x68edf6f5), TOBN(0x7a03aee4, 0xa2b9cb8e)},
+ {TOBN(0x0cd3c376, 0xf53a89aa), TOBN(0x0d8af9b1, 0x948a28dc),
+ TOBN(0xcf86a3f4, 0x902ab04f), TOBN(0x8aacb62a, 0x7f42002d)}},
+ {{TOBN(0x106985eb, 0xf62ffd52), TOBN(0xe670b54e, 0x5797bf10),
+ TOBN(0x4b405209, 0xc5e30aef), TOBN(0x12c97a20, 0x4365b5e9)},
+ {TOBN(0x104646ce, 0x1fe32093), TOBN(0x13cb4ff6, 0x3907a8c9),
+ TOBN(0x8b9f30d1, 0xd46e726b), TOBN(0xe1985e21, 0xaba0f499)}},
+ {{TOBN(0xc573dea9, 0x10a230cd), TOBN(0x24f46a93, 0xcd30f947),
+ TOBN(0xf2623fcf, 0xabe2010a), TOBN(0x3f278cb2, 0x73f00e4f)},
+ {TOBN(0xed55c67d, 0x50b920eb), TOBN(0xf1cb9a2d, 0x8e760571),
+ TOBN(0x7c50d109, 0x0895b709), TOBN(0x4207cf07, 0x190d4369)}},
+ {{TOBN(0x3b027e81, 0xc4127fe1), TOBN(0xa9f8b9ad, 0x3ae9c566),
+ TOBN(0x5ab10851, 0xacbfbba5), TOBN(0xa747d648, 0x569556f5)},
+ {TOBN(0xcc172b5c, 0x2ba97bf7), TOBN(0x15e0f77d, 0xbcfa3324),
+ TOBN(0xa345b797, 0x7686279d), TOBN(0x5a723480, 0xe38003d3)}},
+ {{TOBN(0xfd8e139f, 0x8f5fcda8), TOBN(0xf3e558c4, 0xbdee5bfd),
+ TOBN(0xd76cbaf4, 0xe33f9f77), TOBN(0x3a4c97a4, 0x71771969)},
+ {TOBN(0xda27e84b, 0xf6dce6a7), TOBN(0xff373d96, 0x13e6c2d1),
+ TOBN(0xf115193c, 0xd759a6e9), TOBN(0x3f9b7025, 0x63d2262c)}},
+ {{TOBN(0xd9764a31, 0x317cd062), TOBN(0x30779d8e, 0x199f8332),
+ TOBN(0xd8074106, 0x16b11b0b), TOBN(0x7917ab9f, 0x78aeaed8)},
+ {TOBN(0xb67a9cbe, 0x28fb1d8e), TOBN(0x2e313563, 0x136eda33),
+ TOBN(0x010b7069, 0xa371a86c), TOBN(0x44d90fa2, 0x6744e6b7)}},
+ {{TOBN(0x68190867, 0xd6b3e243), TOBN(0x9fe6cd9d, 0x59048c48),
+ TOBN(0xb900b028, 0x95731538), TOBN(0xa012062f, 0x32cae04f)},
+ {TOBN(0x8107c8bc, 0x9399d082), TOBN(0x47e8c54a, 0x41df12e2),
+ TOBN(0x14ba5117, 0xb6ef3f73), TOBN(0x22260bea, 0x81362f0b)}},
+ {{TOBN(0x90ea261e, 0x1a18cc20), TOBN(0x2192999f, 0x2321d636),
+ TOBN(0xef64d314, 0xe311b6a0), TOBN(0xd7401e4c, 0x3b54a1f5)},
+ {TOBN(0x19019983, 0x6fbca2ba), TOBN(0x46ad3293, 0x8fbffc4b),
+ TOBN(0xa142d3f6, 0x3786bf40), TOBN(0xeb5cbc26, 0xb67039fc)}},
+ {{TOBN(0x9cb0ae6c, 0x252bd479), TOBN(0x05e0f88a, 0x12b5848f),
+ TOBN(0x78f6d2b2, 0xa5c97663), TOBN(0x6f6e149b, 0xc162225c)},
+ {TOBN(0xe602235c, 0xde601a89), TOBN(0xd17bbe98, 0xf373be1f),
+ TOBN(0xcaf49a5b, 0xa8471827), TOBN(0x7e1a0a85, 0x18aaa116)}},
+ {{TOBN(0x6c833196, 0x270580c3), TOBN(0x1e233839, 0xf1c98a14),
+ TOBN(0x67b2f7b4, 0xae34e0a5), TOBN(0x47ac8745, 0xd8ce7289)},
+ {TOBN(0x2b74779a, 0x100dd467), TOBN(0x274a4337, 0x4ee50d09),
+ TOBN(0x603dcf13, 0x83608bc9), TOBN(0xcd9da6c3, 0xc89e8388)}},
+ {{TOBN(0x2660199f, 0x355116ac), TOBN(0xcc38bb59, 0xb6d18eed),
+ TOBN(0x3075f31f, 0x2f4bc071), TOBN(0x9774457f, 0x265dc57e)},
+ {TOBN(0x06a6a9c8, 0xc6db88bb), TOBN(0x6429d07f, 0x4ec98e04),
+ TOBN(0x8d05e57b, 0x05ecaa8b), TOBN(0x20f140b1, 0x7872ea7b)}},
+ {{TOBN(0xdf8c0f09, 0xca494693), TOBN(0x48d3a020, 0xf252e909),
+ TOBN(0x4c5c29af, 0x57b14b12), TOBN(0x7e6fa37d, 0xbf47ad1c)},
+ {TOBN(0x66e7b506, 0x49a0c938), TOBN(0xb72c0d48, 0x6be5f41f),
+ TOBN(0x6a6242b8, 0xb2359412), TOBN(0xcd35c774, 0x8e859480)}},
+ {{TOBN(0x12536fea, 0x87baa627), TOBN(0x58c1fec1, 0xf72aa680),
+ TOBN(0x6c29b637, 0x601e5dc9), TOBN(0x9e3c3c1c, 0xde9e01b9)},
+ {TOBN(0xefc8127b, 0x2bcfe0b0), TOBN(0x35107102, 0x2a12f50d),
+ TOBN(0x6ccd6cb1, 0x4879b397), TOBN(0xf792f804, 0xf8a82f21)}},
+ {{TOBN(0x509d4804, 0xa9b46402), TOBN(0xedddf85d, 0xc10f0850),
+ TOBN(0x928410dc, 0x4b6208aa), TOBN(0xf6229c46, 0x391012dc)},
+ {TOBN(0xc5a7c41e, 0x7727b9b6), TOBN(0x289e4e4b, 0xaa444842),
+ TOBN(0x049ba1d9, 0xe9a947ea), TOBN(0x44f9e47f, 0x83c8debc)}},
+ {{TOBN(0xfa77a1fe, 0x611f8b8e), TOBN(0xfd2e416a, 0xf518f427),
+ TOBN(0xc5fffa70, 0x114ebac3), TOBN(0xfe57c4e9, 0x5d89697b)},
+ {TOBN(0xfdd053ac, 0xb1aaf613), TOBN(0x31df210f, 0xea585a45),
+ TOBN(0x318cc10e, 0x24985034), TOBN(0x1a38efd1, 0x5f1d6130)}},
+ {{TOBN(0xbf86f237, 0x0b1e9e21), TOBN(0xb258514d, 0x1dbe88aa),
+ TOBN(0x1e38a588, 0x90c1baf9), TOBN(0x2936a01e, 0xbdb9b692)},
+ {TOBN(0xd576de98, 0x6dd5b20c), TOBN(0xb586bf71, 0x70f98ecf),
+ TOBN(0xcccf0f12, 0xc42d2fd7), TOBN(0x8717e61c, 0xfb35bd7b)}},
+ {{TOBN(0x8b1e5722, 0x35e6fc06), TOBN(0x3477728f, 0x0b3e13d5),
+ TOBN(0x150c294d, 0xaa8a7372), TOBN(0xc0291d43, 0x3bfa528a)},
+ {TOBN(0xc6c8bc67, 0xcec5a196), TOBN(0xdeeb31e4, 0x5c2e8a7c),
+ TOBN(0xba93e244, 0xfb6e1c51), TOBN(0xb9f8b71b, 0x2e28e156)}},
+ {{TOBN(0xce65a287, 0x968a2ab9), TOBN(0xe3c5ce69, 0x46bbcb1f),
+ TOBN(0xf8c835b9, 0xe7ae3f30), TOBN(0x16bbee26, 0xff72b82b)},
+ {TOBN(0x665e2017, 0xfd42cd22), TOBN(0x1e139970, 0xf8b1d2a0),
+ TOBN(0x125cda29, 0x79204932), TOBN(0x7aee94a5, 0x49c3bee5)}},
+ {{TOBN(0x68c70160, 0x89821a66), TOBN(0xf7c37678, 0x8f981669),
+ TOBN(0xd90829fc, 0x48cc3645), TOBN(0x346af049, 0xd70addfc)},
+ {TOBN(0x2057b232, 0x370bf29c), TOBN(0xf90c73ce, 0x42e650ee),
+ TOBN(0xe03386ea, 0xa126ab90), TOBN(0x0e266e7e, 0x975a087b)}},
+ {{TOBN(0x80578eb9, 0x0fca65d9), TOBN(0x7e2989ea, 0x16af45b8),
+ TOBN(0x7438212d, 0xcac75a4e), TOBN(0x38c7ca39, 0x4fef36b8)},
+ {TOBN(0x8650c494, 0xd402676a), TOBN(0x26ab5a66, 0xf72c7c48),
+ TOBN(0x4e6cb426, 0xce3a464e), TOBN(0xf8f99896, 0x2b72f841)}},
+ {{TOBN(0x8c318491, 0x1a335cc8), TOBN(0x563459ba, 0x6a5913e4),
+ TOBN(0x1b920d61, 0xc7b32919), TOBN(0x805ab8b6, 0xa02425ad)},
+ {TOBN(0x2ac512da, 0x8d006086), TOBN(0x6ca4846a, 0xbcf5c0fd),
+ TOBN(0xafea51d8, 0xac2138d7), TOBN(0xcb647545, 0x344cd443)}},
+ {{TOBN(0x0429ee8f, 0xbd7d9040), TOBN(0xee66a2de, 0x819b9c96),
+ TOBN(0x54f9ec25, 0xdea7d744), TOBN(0x2ffea642, 0x671721bb)},
+ {TOBN(0x4f19dbd1, 0x114344ea), TOBN(0x04304536, 0xfd0dbc8b),
+ TOBN(0x014b50aa, 0x29ec7f91), TOBN(0xb5fc22fe, 0xbb06014d)}},
+ {{TOBN(0x60d963a9, 0x1ee682e0), TOBN(0xdf48abc0, 0xfe85c727),
+ TOBN(0x0cadba13, 0x2e707c2d), TOBN(0xde608d3a, 0xa645aeff)},
+ {TOBN(0x05f1c28b, 0xedafd883), TOBN(0x3c362ede, 0xbd94de1f),
+ TOBN(0x8dd0629d, 0x13593e41), TOBN(0x0a5e736f, 0x766d6eaf)}},
+ {{TOBN(0xbfa92311, 0xf68cf9d1), TOBN(0xa4f9ef87, 0xc1797556),
+ TOBN(0x10d75a1f, 0x5601c209), TOBN(0x651c374c, 0x09b07361)},
+ {TOBN(0x49950b58, 0x88b5cead), TOBN(0x0ef00058, 0x6fa9dbaa),
+ TOBN(0xf51ddc26, 0x4e15f33a), TOBN(0x1f8b5ca6, 0x2ef46140)}},
+ {{TOBN(0x343ac0a3, 0xee9523f0), TOBN(0xbb75eab2, 0x975ea978),
+ TOBN(0x1bccf332, 0x107387f4), TOBN(0x790f9259, 0x9ab0062e)},
+ {TOBN(0xf1a363ad, 0x1e4f6a5f), TOBN(0x06e08b84, 0x62519a50),
+ TOBN(0x60915187, 0x7265f1ee), TOBN(0x6a80ca34, 0x93ae985e)}},
+ {{TOBN(0x81b29768, 0xaaba4864), TOBN(0xb13cabf2, 0x8d52a7d6),
+ TOBN(0xb5c36348, 0x8ead03f1), TOBN(0xc932ad95, 0x81c7c1c0)},
+ {TOBN(0x5452708e, 0xcae1e27b), TOBN(0x9dac4269, 0x1b0df648),
+ TOBN(0x233e3f0c, 0xdfcdb8bc), TOBN(0xe6ceccdf, 0xec540174)}},
+ {{TOBN(0xbd0d845e, 0x95081181), TOBN(0xcc8a7920, 0x699355d5),
+ TOBN(0x111c0f6d, 0xc3b375a8), TOBN(0xfd95bc6b, 0xfd51e0dc)},
+ {TOBN(0x4a106a26, 0x6888523a), TOBN(0x4d142bd6, 0xcb01a06d),
+ TOBN(0x79bfd289, 0xadb9b397), TOBN(0x0bdbfb94, 0xe9863914)}},
+ {{TOBN(0x29d8a229, 0x1660f6a6), TOBN(0x7f6abcd6, 0x551c042d),
+ TOBN(0x13039deb, 0x0ac3ffe8), TOBN(0xa01be628, 0xec8523fb)},
+ {TOBN(0x6ea34103, 0x0ca1c328), TOBN(0xc74114bd, 0xb903928e),
+ TOBN(0x8aa4ff4e, 0x9e9144b0), TOBN(0x7064091f, 0x7f9a4b17)}},
+ {{TOBN(0xa3f4f521, 0xe447f2c4), TOBN(0x81b8da7a, 0x604291f0),
+ TOBN(0xd680bc46, 0x7d5926de), TOBN(0x84f21fd5, 0x34a1202f)},
+ {TOBN(0x1d1e3181, 0x4e9df3d8), TOBN(0x1ca4861a, 0x39ab8d34),
+ TOBN(0x809ddeec, 0x5b19aa4a), TOBN(0x59f72f7e, 0x4d329366)}},
+ {{TOBN(0xa2f93f41, 0x386d5087), TOBN(0x40bf739c, 0xdd67d64f),
+ TOBN(0xb4494205, 0x66702158), TOBN(0xc33c65be, 0x73b1e178)},
+ {TOBN(0xcdcd657c, 0x38ca6153), TOBN(0x97f4519a, 0xdc791976),
+ TOBN(0xcc7c7f29, 0xcd6e1f39), TOBN(0x38de9cfb, 0x7e3c3932)}},
+ {{TOBN(0xe448eba3, 0x7b793f85), TOBN(0xe9f8dbf9, 0xf067e914),
+ TOBN(0xc0390266, 0xf114ae87), TOBN(0x39ed75a7, 0xcd6a8e2a)},
+ {TOBN(0xadb14848, 0x7ffba390), TOBN(0x67f8cb8b, 0x6af9bc09),
+ TOBN(0x322c3848, 0x9c7476db), TOBN(0xa320fecf, 0x52a538d6)}},
+ {{TOBN(0xe0493002, 0xb2aced2b), TOBN(0xdfba1809, 0x616bd430),
+ TOBN(0x531c4644, 0xc331be70), TOBN(0xbc04d32e, 0x90d2e450)},
+ {TOBN(0x1805a0d1, 0x0f9f142d), TOBN(0x2c44a0c5, 0x47ee5a23),
+ TOBN(0x31875a43, 0x3989b4e3), TOBN(0x6b1949fd, 0x0c063481)}},
+ {{TOBN(0x2dfb9e08, 0xbe0f4492), TOBN(0x3ff0da03, 0xe9d5e517),
+ TOBN(0x03dbe9a1, 0xf79466a8), TOBN(0x0b87bcd0, 0x15ea9932)},
+ {TOBN(0xeb64fc83, 0xab1f58ab), TOBN(0x6d9598da, 0x817edc8a),
+ TOBN(0x699cff66, 0x1d3b67e5), TOBN(0x645c0f29, 0x92635853)}},
+ {{TOBN(0x253cdd82, 0xeabaf21c), TOBN(0x82b9602a, 0x2241659e),
+ TOBN(0x2cae07ec, 0x2d9f7091), TOBN(0xbe4c720c, 0x8b48cd9b)},
+ {TOBN(0x6ce5bc03, 0x6f08d6c9), TOBN(0x36e8a997, 0xaf10bf40),
+ TOBN(0x83422d21, 0x3e10ff12), TOBN(0x7b26d3eb, 0xbcc12494)}},
+ {{TOBN(0xb240d2d0, 0xc9469ad6), TOBN(0xc4a11b4d, 0x30afa05b),
+ TOBN(0x4b604ace, 0xdd6ba286), TOBN(0x18486600, 0x3ee2864c)},
+ {TOBN(0x5869d6ba, 0x8d9ce5be), TOBN(0x0d8f68c5, 0xff4bfb0d),
+ TOBN(0xb69f210b, 0x5700cf73), TOBN(0x61f6653a, 0x6d37c135)}},
+ {{TOBN(0xff3d432b, 0x5aff5a48), TOBN(0x0d81c4b9, 0x72ba3a69),
+ TOBN(0xee879ae9, 0xfa1899ef), TOBN(0xbac7e2a0, 0x2d6acafd)},
+ {TOBN(0xd6d93f6c, 0x1c664399), TOBN(0x4c288de1, 0x5bcb135d),
+ TOBN(0x83031dab, 0x9dab7cbf), TOBN(0xfe23feb0, 0x3abbf5f0)}},
+ {{TOBN(0x9f1b2466, 0xcdedca85), TOBN(0x140bb710, 0x1a09538c),
+ TOBN(0xac8ae851, 0x5e11115d), TOBN(0x0d63ff67, 0x6f03f59e)},
+ {TOBN(0x755e5551, 0x7d234afb), TOBN(0x61c2db4e, 0x7e208fc1),
+ TOBN(0xaa9859ce, 0xf28a4b5d), TOBN(0xbdd6d4fc, 0x34af030f)}},
+ {{TOBN(0xd1c4a26d, 0x3be01cb1), TOBN(0x9ba14ffc, 0x243aa07c),
+ TOBN(0xf95cd3a9, 0xb2503502), TOBN(0xe379bc06, 0x7d2a93ab)},
+ {TOBN(0x3efc18e9, 0xd4ca8d68), TOBN(0x083558ec, 0x80bb412a),
+ TOBN(0xd903b940, 0x9645a968), TOBN(0xa499f0b6, 0x9ba6054f)}},
+ {{TOBN(0x208b573c, 0xb8349abe), TOBN(0x3baab3e5, 0x30b4fc1c),
+ TOBN(0x87e978ba, 0xcb524990), TOBN(0x3524194e, 0xccdf0e80)},
+ {TOBN(0x62711725, 0x7d4bcc42), TOBN(0xe90a3d9b, 0xb90109ba),
+ TOBN(0x3b1bdd57, 0x1323e1e0), TOBN(0xb78e9bd5, 0x5eae1599)}},
+ {{TOBN(0x0794b746, 0x9e03d278), TOBN(0x80178605, 0xd70e6297),
+ TOBN(0x171792f8, 0x99c97855), TOBN(0x11b393ee, 0xf5a86b5c)},
+ {TOBN(0x48ef6582, 0xd8884f27), TOBN(0xbd44737a, 0xbf19ba5f),
+ TOBN(0x8698de4c, 0xa42062c6), TOBN(0x8975eb80, 0x61ce9c54)}},
+ {{TOBN(0xd50e57c7, 0xd7fe71f3), TOBN(0x15342190, 0xbc97ce38),
+ TOBN(0x51bda2de, 0x4df07b63), TOBN(0xba12aeae, 0x200eb87d)},
+ {TOBN(0xabe135d2, 0xa9b4f8f6), TOBN(0x04619d65, 0xfad6d99c),
+ TOBN(0x4a6683a7, 0x7994937c), TOBN(0x7a778c8b, 0x6f94f09a)}},
+ {{TOBN(0x8c508623, 0x20a71b89), TOBN(0x241a2aed, 0x1c229165),
+ TOBN(0x352be595, 0xaaf83a99), TOBN(0x9fbfee7f, 0x1562bac8)},
+ {TOBN(0xeaf658b9, 0x5c4017e3), TOBN(0x1dc7f9e0, 0x15120b86),
+ TOBN(0xd84f13dd, 0x4c034d6f), TOBN(0x283dd737, 0xeaea3038)}},
+ {{TOBN(0x197f2609, 0xcd85d6a2), TOBN(0x6ebbc345, 0xfae60177),
+ TOBN(0xb80f031b, 0x4e12fede), TOBN(0xde55d0c2, 0x07a2186b)},
+ {TOBN(0x1fb3e37f, 0x24dcdd5a), TOBN(0x8d602da5, 0x7ed191fb),
+ TOBN(0x108fb056, 0x76023e0d), TOBN(0x70178c71, 0x459c20c0)}},
+ {{TOBN(0xfad5a386, 0x3fe54cf0), TOBN(0xa4a3ec4f, 0x02bbb475),
+ TOBN(0x1aa5ec20, 0x919d94d7), TOBN(0x5d3b63b5, 0xa81e4ab3)},
+ {TOBN(0x7fa733d8, 0x5ad3d2af), TOBN(0xfbc586dd, 0xd1ac7a37),
+ TOBN(0x282925de, 0x40779614), TOBN(0xfe0ffffb, 0xe74a242a)}},
+ {{TOBN(0x3f39e67f, 0x906151e5), TOBN(0xcea27f5f, 0x55e10649),
+ TOBN(0xdca1d4e1, 0xc17cf7b7), TOBN(0x0c326d12, 0x2fe2362d)},
+ {TOBN(0x05f7ac33, 0x7dd35df3), TOBN(0x0c3b7639, 0xc396dbdf),
+ TOBN(0x0912f5ac, 0x03b7db1c), TOBN(0x9dea4b70, 0x5c9ed4a9)}},
+ {{TOBN(0x475e6e53, 0xaae3f639), TOBN(0xfaba0e7c, 0xfc278bac),
+ TOBN(0x16f9e221, 0x9490375f), TOBN(0xaebf9746, 0xa5a7ed0a)},
+ {TOBN(0x45f9af3f, 0xf41ad5d6), TOBN(0x03c4623c, 0xb2e99224),
+ TOBN(0x82c5bb5c, 0xb3cf56aa), TOBN(0x64311819, 0x34567ed3)}},
+ {{TOBN(0xec57f211, 0x8be489ac), TOBN(0x2821895d, 0xb9a1104b),
+ TOBN(0x610dc875, 0x6064e007), TOBN(0x8e526f3f, 0x5b20d0fe)},
+ {TOBN(0x6e71ca77, 0x5b645aee), TOBN(0x3d1dcb9f, 0x800e10ff),
+ TOBN(0x36b51162, 0x189cf6de), TOBN(0x2c5a3e30, 0x6bb17353)}},
+ {{TOBN(0xc186cd3e, 0x2a6c6fbf), TOBN(0xa74516fa, 0x4bf97906),
+ TOBN(0x5b4b8f4b, 0x279d6901), TOBN(0x0c4e57b4, 0x2b573743)},
+ {TOBN(0x75fdb229, 0xb6e386b6), TOBN(0xb46793fd, 0x99deac27),
+ TOBN(0xeeec47ea, 0xcf712629), TOBN(0xe965f3c4, 0xcbc3b2dd)}},
+ {{TOBN(0x8dd1fb83, 0x425c6559), TOBN(0x7fc00ee6, 0x0af06fda),
+ TOBN(0xe98c9225, 0x33d956df), TOBN(0x0f1ef335, 0x4fbdc8a2)},
+ {TOBN(0x2abb5145, 0xb79b8ea2), TOBN(0x40fd2945, 0xbdbff288),
+ TOBN(0x6a814ac4, 0xd7185db7), TOBN(0xc4329d6f, 0xc084609a)}},
+ {{TOBN(0xc9ba7b52, 0xed1be45d), TOBN(0x891dd20d, 0xe4cd2c74),
+ TOBN(0x5a4d4a7f, 0x824139b1), TOBN(0x66c17716, 0xb873c710)},
+ {TOBN(0x5e5bc141, 0x2843c4e0), TOBN(0xd5ac4817, 0xb97eb5bf),
+ TOBN(0xc0f8af54, 0x450c95c7), TOBN(0xc91b3fa0, 0x318406c5)}},
+ {{TOBN(0x360c340a, 0xab9d97f8), TOBN(0xfb57bd07, 0x90a2d611),
+ TOBN(0x4339ae3c, 0xa6a6f7e5), TOBN(0x9c1fcd2a, 0x2feb8a10)},
+ {TOBN(0x972bcca9, 0xc7ea7432), TOBN(0x1b0b924c, 0x308076f6),
+ TOBN(0x80b2814a, 0x2a5b4ca5), TOBN(0x2f78f55b, 0x61ef3b29)}},
+ {{TOBN(0xf838744a, 0xc18a414f), TOBN(0xc611eaae, 0x903d0a86),
+ TOBN(0x94dabc16, 0x2a453f55), TOBN(0xe6f2e3da, 0x14efb279)},
+ {TOBN(0x5b7a6017, 0x9320dc3c), TOBN(0x692e382f, 0x8df6b5a4),
+ TOBN(0x3f5e15e0, 0x2d40fa90), TOBN(0xc87883ae, 0x643dd318)}},
+ {{TOBN(0x511053e4, 0x53544774), TOBN(0x834d0ecc, 0x3adba2bc),
+ TOBN(0x4215d7f7, 0xbae371f5), TOBN(0xfcfd57bf, 0x6c8663bc)},
+ {TOBN(0xded2383d, 0xd6901b1d), TOBN(0x3b49fbb4, 0xb5587dc3),
+ TOBN(0xfd44a08d, 0x07625f62), TOBN(0x3ee4d65b, 0x9de9b762)}}},
+ {{{TOBN(0x64e5137d, 0x0d63d1fa), TOBN(0x658fc052, 0x02a9d89f),
+ TOBN(0x48894874, 0x50436309), TOBN(0xe9ae30f8, 0xd598da61)},
+ {TOBN(0x2ed710d1, 0x818baf91), TOBN(0xe27e9e06, 0x8b6a0c20),
+ TOBN(0x1e28dcfb, 0x1c1a6b44), TOBN(0x883acb64, 0xd6ac57dc)}},
+ {{TOBN(0x8735728d, 0xc2c6ff70), TOBN(0x79d6122f, 0xc5dc2235),
+ TOBN(0x23f5d003, 0x19e277f9), TOBN(0x7ee84e25, 0xdded8cc7)},
+ {TOBN(0x91a8afb0, 0x63cd880a), TOBN(0x3f3ea7c6, 0x3574af60),
+ TOBN(0x0cfcdc84, 0x02de7f42), TOBN(0x62d0792f, 0xb31aa152)}},
+ {{TOBN(0x8e1b4e43, 0x8a5807ce), TOBN(0xad283893, 0xe4109a7e),
+ TOBN(0xc30cc9cb, 0xafd59dda), TOBN(0xf65f36c6, 0x3d8d8093)},
+ {TOBN(0xdf31469e, 0xa60d32b2), TOBN(0xee93df4b, 0x3e8191c8),
+ TOBN(0x9c1017c5, 0x355bdeb5), TOBN(0xd2623185, 0x8616aa28)}},
+ {{TOBN(0xb02c83f9, 0xdec31a21), TOBN(0x988c8b23, 0x6ad9d573),
+ TOBN(0x53e983ae, 0xa57be365), TOBN(0xe968734d, 0x646f834e)},
+ {TOBN(0x9137ea8f, 0x5da6309b), TOBN(0x10f3a624, 0xc1f1ce16),
+ TOBN(0x782a9ea2, 0xca440921), TOBN(0xdf94739e, 0x5b46f1b5)}},
+ {{TOBN(0x9f9be006, 0xcce85c9b), TOBN(0x360e70d6, 0xa4c7c2d3),
+ TOBN(0x2cd5beea, 0xaefa1e60), TOBN(0x64cf63c0, 0x8c3d2b6d)},
+ {TOBN(0xfb107fa3, 0xe1cf6f90), TOBN(0xb7e937c6, 0xd5e044e6),
+ TOBN(0x74e8ca78, 0xce34db9f), TOBN(0x4f8b36c1, 0x3e210bd0)}},
+ {{TOBN(0x1df165a4, 0x34a35ea8), TOBN(0x3418e0f7, 0x4d4412f6),
+ TOBN(0x5af1f8af, 0x518836c3), TOBN(0x42ceef4d, 0x130e1965)},
+ {TOBN(0x5560ca0b, 0x543a1957), TOBN(0xc33761e5, 0x886cb123),
+ TOBN(0x66624b1f, 0xfe98ed30), TOBN(0xf772f4bf, 0x1090997d)}},
+ {{TOBN(0xf4e540bb, 0x4885d410), TOBN(0x7287f810, 0x9ba5f8d7),
+ TOBN(0x22d0d865, 0xde98dfb1), TOBN(0x49ff51a1, 0xbcfbb8a3)},
+ {TOBN(0xb6b6fa53, 0x6bc3012e), TOBN(0x3d31fd72, 0x170d541d),
+ TOBN(0x8018724f, 0x4b0f4966), TOBN(0x79e7399f, 0x87dbde07)}},
+ {{TOBN(0x56f8410e, 0xf4f8b16a), TOBN(0x97241afe, 0xc47b266a),
+ TOBN(0x0a406b8e, 0x6d9c87c1), TOBN(0x803f3e02, 0xcd42ab1b)},
+ {TOBN(0x7f0309a8, 0x04dbec69), TOBN(0xa83b85f7, 0x3bbad05f),
+ TOBN(0xc6097273, 0xad8e197f), TOBN(0xc097440e, 0x5067adc1)}},
+ {{TOBN(0x730eafb6, 0x3524ff16), TOBN(0xd7f9b51e, 0x823fc6ce),
+ TOBN(0x27bd0d32, 0x443e4ac0), TOBN(0x40c59ad9, 0x4d66f217)},
+ {TOBN(0x6c33136f, 0x17c387a4), TOBN(0x5043b8d5, 0xeb86804d),
+ TOBN(0x74970312, 0x675a73c9), TOBN(0x838fdb31, 0xf16669b6)}},
+ {{TOBN(0xc507b6dd, 0x418e7ddd), TOBN(0x39888d93, 0x472f19d6),
+ TOBN(0x7eae26be, 0x0c27eb4d), TOBN(0x17b53ed3, 0xfbabb884)},
+ {TOBN(0xfc27021b, 0x2b01ae4f), TOBN(0x88462e87, 0xcf488682),
+ TOBN(0xbee096ec, 0x215e2d87), TOBN(0xeb2fea9a, 0xd242e29b)}},
+ {{TOBN(0x5d985b5f, 0xb821fc28), TOBN(0x89d2e197, 0xdc1e2ad2),
+ TOBN(0x55b566b8, 0x9030ba62), TOBN(0xe3fd41b5, 0x4f41b1c6)},
+ {TOBN(0xb738ac2e, 0xb9a96d61), TOBN(0x7f8567ca, 0x369443f4),
+ TOBN(0x8698622d, 0xf803a440), TOBN(0x2b586236, 0x8fe2f4dc)}},
+ {{TOBN(0xbbcc00c7, 0x56b95bce), TOBN(0x5ec03906, 0x616da680),
+ TOBN(0x79162ee6, 0x72214252), TOBN(0x43132b63, 0x86a892d2)},
+ {TOBN(0x4bdd3ff2, 0x2f3263bf), TOBN(0xd5b3733c, 0x9cd0a142),
+ TOBN(0x592eaa82, 0x44415ccb), TOBN(0x663e8924, 0x8d5474ea)}},
+ {{TOBN(0x8058a25e, 0x5236344e), TOBN(0x82e8df9d, 0xbda76ee6),
+ TOBN(0xdcf6efd8, 0x11cc3d22), TOBN(0x00089cda, 0x3b4ab529)},
+ {TOBN(0x91d3a071, 0xbd38a3db), TOBN(0x4ea97fc0, 0xef72b925),
+ TOBN(0x0c9fc15b, 0xea3edf75), TOBN(0x5a6297cd, 0xa4348ed3)}},
+ {{TOBN(0x0d38ab35, 0xce7c42d4), TOBN(0x9fd493ef, 0x82feab10),
+ TOBN(0x46056b6d, 0x82111b45), TOBN(0xda11dae1, 0x73efc5c3)},
+ {TOBN(0xdc740278, 0x5545a7fb), TOBN(0xbdb2601c, 0x40d507e6),
+ TOBN(0x121dfeeb, 0x7066fa58), TOBN(0x214369a8, 0x39ae8c2a)}},
+ {{TOBN(0x195709cb, 0x06e0956c), TOBN(0x4c9d254f, 0x010cd34b),
+ TOBN(0xf51e13f7, 0x0471a532), TOBN(0xe19d6791, 0x1e73054d)},
+ {TOBN(0xf702a628, 0xdb5c7be3), TOBN(0xc7141218, 0xb24dde05),
+ TOBN(0xdc18233c, 0xf29b2e2e), TOBN(0x3a6bd1e8, 0x85342dba)}},
+ {{TOBN(0x3f747fa0, 0xb311898c), TOBN(0xe2a272e4, 0xcd0eac65),
+ TOBN(0x4bba5851, 0xf914d0bc), TOBN(0x7a1a9660, 0xc4a43ee3)},
+ {TOBN(0xe5a367ce, 0xa1c8cde9), TOBN(0x9d958ba9, 0x7271abe3),
+ TOBN(0xf3ff7eb6, 0x3d1615cd), TOBN(0xa2280dce, 0xf5ae20b0)}},
+ {{TOBN(0x56dba5c1, 0xcf640147), TOBN(0xea5a2e3d, 0x5e83d118),
+ TOBN(0x04cd6b6d, 0xda24c511), TOBN(0x1c0f4671, 0xe854d214)},
+ {TOBN(0x91a6b7a9, 0x69565381), TOBN(0xdc966240, 0xdecf1f5b),
+ TOBN(0x1b22d21c, 0xfcf5d009), TOBN(0x2a05f641, 0x9021dbd5)}},
+ {{TOBN(0x8c0ed566, 0xd4312483), TOBN(0x5179a95d, 0x643e216f),
+ TOBN(0xcc185fec, 0x17044493), TOBN(0xb3063339, 0x54991a21)},
+ {TOBN(0xd801ecdb, 0x0081a726), TOBN(0x0149b0c6, 0x4fa89bbb),
+ TOBN(0xafe9065a, 0x4391b6b9), TOBN(0xedc92786, 0xd633f3a3)}},
+ {{TOBN(0xe408c24a, 0xae6a8e13), TOBN(0x85833fde, 0x9f3897ab),
+ TOBN(0x43800e7e, 0xd81a0715), TOBN(0xde08e346, 0xb44ffc5f)},
+ {TOBN(0x7094184c, 0xcdeff2e0), TOBN(0x49f9387b, 0x165eaed1),
+ TOBN(0x635d6129, 0x777c468a), TOBN(0x8c0dcfd1, 0x538c2dd8)}},
+ {{TOBN(0xd6d9d9e3, 0x7a6a308b), TOBN(0x62375830, 0x4c2767d3),
+ TOBN(0x874a8bc6, 0xf38cbeb6), TOBN(0xd94d3f1a, 0xccb6fd9e)},
+ {TOBN(0x92a9735b, 0xba21f248), TOBN(0x272ad0e5, 0x6cd1efb0),
+ TOBN(0x7437b69c, 0x05b03284), TOBN(0xe7f04702, 0x6948c225)}},
+ {{TOBN(0x8a56c04a, 0xcba2ecec), TOBN(0x0c181270, 0xe3a73e41),
+ TOBN(0x6cb34e9d, 0x03e93725), TOBN(0xf77c8713, 0x496521a9)},
+ {TOBN(0x94569183, 0xfa7f9f90), TOBN(0xf2e7aa4c, 0x8c9707ad),
+ TOBN(0xced2c9ba, 0x26c1c9a3), TOBN(0x9109fe96, 0x40197507)}},
+ {{TOBN(0x9ae868a9, 0xe9adfe1c), TOBN(0x3984403d, 0x314e39bb),
+ TOBN(0xb5875720, 0xf2fe378f), TOBN(0x33f901e0, 0xba44a628)},
+ {TOBN(0xea1125fe, 0x3652438c), TOBN(0xae9ec4e6, 0x9dd1f20b),
+ TOBN(0x1e740d9e, 0xbebf7fbd), TOBN(0x6dbd3ddc, 0x42dbe79c)}},
+ {{TOBN(0x62082aec, 0xedd36776), TOBN(0xf612c478, 0xe9859039),
+ TOBN(0xa493b201, 0x032f7065), TOBN(0xebd4d8f2, 0x4ff9b211)},
+ {TOBN(0x3f23a0aa, 0xaac4cb32), TOBN(0xea3aadb7, 0x15ed4005),
+ TOBN(0xacf17ea4, 0xafa27e63), TOBN(0x56125c1a, 0xc11fd66c)}},
+ {{TOBN(0x266344a4, 0x3794f8dc), TOBN(0xdcca923a, 0x483c5c36),
+ TOBN(0x2d6b6bbf, 0x3f9d10a0), TOBN(0xb320c5ca, 0x81d9bdf3)},
+ {TOBN(0x620e28ff, 0x47b50a95), TOBN(0x933e3b01, 0xcef03371),
+ TOBN(0xf081bf85, 0x99100153), TOBN(0x183be9a0, 0xc3a8c8d6)}},
+ {{TOBN(0x4e3ddc5a, 0xd6bbe24d), TOBN(0xc6c74630, 0x53843795),
+ TOBN(0x78193dd7, 0x65ec2d4c), TOBN(0xb8df26cc, 0xcd3c89b2)},
+ {TOBN(0x98dbe399, 0x5a483f8d), TOBN(0x72d8a957, 0x7dd3313a),
+ TOBN(0x65087294, 0xab0bd375), TOBN(0xfcd89248, 0x7c259d16)}},
+ {{TOBN(0x8a9443d7, 0x7613aa81), TOBN(0x80100800, 0x85fe6584),
+ TOBN(0x70fc4dbc, 0x7fb10288), TOBN(0xf58280d3, 0xe86beee8)},
+ {TOBN(0x14fdd82f, 0x7c978c38), TOBN(0xdf1204c1, 0x0de44d7b),
+ TOBN(0xa08a1c84, 0x4160252f), TOBN(0x591554ca, 0xc17646a5)}},
+ {{TOBN(0x214a37d6, 0xa05bd525), TOBN(0x48d5f09b, 0x07957b3c),
+ TOBN(0x0247cdcb, 0xd7109bc9), TOBN(0x40f9e4bb, 0x30599ce7)},
+ {TOBN(0xc325fa03, 0xf46ad2ec), TOBN(0x00f766cf, 0xc3e3f9ee),
+ TOBN(0xab556668, 0xd43a4577), TOBN(0x68d30a61, 0x3ee03b93)}},
+ {{TOBN(0x7ddc81ea, 0x77b46a08), TOBN(0xcf5a6477, 0xc7480699),
+ TOBN(0x43a8cb34, 0x6633f683), TOBN(0x1b867e6b, 0x92363c60)},
+ {TOBN(0x43921114, 0x1f60558e), TOBN(0xcdbcdd63, 0x2f41450e),
+ TOBN(0x7fc04601, 0xcc630e8b), TOBN(0xea7c66d5, 0x97038b43)}},
+ {{TOBN(0x7259b8a5, 0x04e99fd8), TOBN(0x98a8dd12, 0x4785549a),
+ TOBN(0x0e459a7c, 0x840552e1), TOBN(0xcdfcf4d0, 0x4bb0909e)},
+ {TOBN(0x34a86db2, 0x53758da7), TOBN(0xe643bb83, 0xeac997e1),
+ TOBN(0x96400bd7, 0x530c5b7e), TOBN(0x9f97af87, 0xb41c8b52)}},
+ {{TOBN(0x34fc8820, 0xfbeee3f9), TOBN(0x93e53490, 0x49091afd),
+ TOBN(0x764b9be5, 0x9a31f35c), TOBN(0x71f37864, 0x57e3d924)},
+ {TOBN(0x02fb34e0, 0x943aa75e), TOBN(0xa18c9c58, 0xab8ff6e4),
+ TOBN(0x080f31b1, 0x33cf0d19), TOBN(0x5c9682db, 0x083518a7)}},
+ {{TOBN(0x873d4ca6, 0xb709c3de), TOBN(0x64a84262, 0x3575b8f0),
+ TOBN(0x6275da1f, 0x020154bb), TOBN(0x97678caa, 0xd17cf1ab)},
+ {TOBN(0x8779795f, 0x951a95c3), TOBN(0xdd35b163, 0x50fccc08),
+ TOBN(0x32709627, 0x33d8f031), TOBN(0x3c5ab10a, 0x498dd85c)}},
+ {{TOBN(0xb6c185c3, 0x41dca566), TOBN(0x7de7feda, 0xd8622aa3),
+ TOBN(0x99e84d92, 0x901b6dfb), TOBN(0x30a02b0e, 0x7c4ad288)},
+ {TOBN(0xc7c81daa, 0x2fd3cf36), TOBN(0xd1319547, 0xdf89e59f),
+ TOBN(0xb2be8184, 0xcd496733), TOBN(0xd5f449eb, 0x93d3412b)}},
+ {{TOBN(0x7ea41b1b, 0x25fe531d), TOBN(0xf9797432, 0x6a1d5646),
+ TOBN(0x86067f72, 0x2bde501a), TOBN(0xf91481c0, 0x0c85e89c)},
+ {TOBN(0xca8ee465, 0xf8b05bc6), TOBN(0x1844e1cf, 0x02e83cda),
+ TOBN(0xca82114a, 0xb4dbe33b), TOBN(0x0f9f8769, 0x4eabfde2)}},
+ {{TOBN(0x4936b1c0, 0x38b27fe2), TOBN(0x63b6359b, 0xaba402df),
+ TOBN(0x40c0ea2f, 0x656bdbab), TOBN(0x9c992a89, 0x6580c39c)},
+ {TOBN(0x600e8f15, 0x2a60aed1), TOBN(0xeb089ca4, 0xe0bf49df),
+ TOBN(0x9c233d7d, 0x2d42d99a), TOBN(0x648d3f95, 0x4c6bc2fa)}},
+ {{TOBN(0xdcc383a8, 0xe1add3f3), TOBN(0xf42c0c6a, 0x4f64a348),
+ TOBN(0x2abd176f, 0x0030dbdb), TOBN(0x4de501a3, 0x7d6c215e)},
+ {TOBN(0x4a107c1f, 0x4b9a64bc), TOBN(0xa77f0ad3, 0x2496cd59),
+ TOBN(0xfb78ac62, 0x7688dffb), TOBN(0x7025a2ca, 0x67937d8e)}},
+ {{TOBN(0xfde8b2d1, 0xd1a8f4e7), TOBN(0xf5b3da47, 0x7354927c),
+ TOBN(0xe48606a3, 0xd9205735), TOBN(0xac477cc6, 0xe177b917)},
+ {TOBN(0xfb1f73d2, 0xa883239a), TOBN(0xe12572f6, 0xcc8b8357),
+ TOBN(0x9d355e9c, 0xfb1f4f86), TOBN(0x89b795f8, 0xd9f3ec6e)}},
+ {{TOBN(0x27be56f1, 0xb54398dc), TOBN(0x1890efd7, 0x3fedeed5),
+ TOBN(0x62f77f1f, 0x9c6d0140), TOBN(0x7ef0e314, 0x596f0ee4)},
+ {TOBN(0x50ca6631, 0xcc61dab3), TOBN(0x4a39801d, 0xf4866e4f),
+ TOBN(0x66c8d032, 0xae363b39), TOBN(0x22c591e5, 0x2ead66aa)}},
+ {{TOBN(0x954ba308, 0xde02a53e), TOBN(0x2a6c060f, 0xd389f357),
+ TOBN(0xe6cfcde8, 0xfbf40b66), TOBN(0x8e02fc56, 0xc6340ce1)},
+ {TOBN(0xe4957795, 0x73adb4ba), TOBN(0x7b86122c, 0xa7b03805),
+ TOBN(0x63f83512, 0x0c8e6fa6), TOBN(0x83660ea0, 0x057d7804)}},
+ {{TOBN(0xbad79105, 0x21ba473c), TOBN(0xb6c50bee, 0xded5389d),
+ TOBN(0xee2caf4d, 0xaa7c9bc0), TOBN(0xd97b8de4, 0x8c4e98a7)},
+ {TOBN(0xa9f63e70, 0xab3bbddb), TOBN(0x3898aabf, 0x2597815a),
+ TOBN(0x7659af89, 0xac15b3d9), TOBN(0xedf7725b, 0x703ce784)}},
+ {{TOBN(0x25470fab, 0xe085116b), TOBN(0x04a43375, 0x87285310),
+ TOBN(0x4e39187e, 0xe2bfd52f), TOBN(0x36166b44, 0x7d9ebc74)},
+ {TOBN(0x92ad433c, 0xfd4b322c), TOBN(0x726aa817, 0xba79ab51),
+ TOBN(0xf96eacd8, 0xc1db15eb), TOBN(0xfaf71e91, 0x0476be63)}},
+ {{TOBN(0xdd69a640, 0x641fad98), TOBN(0xb7995918, 0x29622559),
+ TOBN(0x03c6daa5, 0xde4199dc), TOBN(0x92cadc97, 0xad545eb4)},
+ {TOBN(0x1028238b, 0x256534e4), TOBN(0x73e80ce6, 0x8595409a),
+ TOBN(0x690d4c66, 0xd05dc59b), TOBN(0xc95f7b8f, 0x981dee80)}},
+ {{TOBN(0xf4337014, 0xd856ac25), TOBN(0x441bd9dd, 0xac524dca),
+ TOBN(0x640b3d85, 0x5f0499f5), TOBN(0x39cf84a9, 0xd5fda182)},
+ {TOBN(0x04e7b055, 0xb2aa95a0), TOBN(0x29e33f0a, 0x0ddf1860),
+ TOBN(0x082e74b5, 0x423f6b43), TOBN(0x217edeb9, 0x0aaa2b0f)}},
+ {{TOBN(0x58b83f35, 0x83cbea55), TOBN(0xc485ee4d, 0xbc185d70),
+ TOBN(0x833ff03b, 0x1e5f6992), TOBN(0xb5b9b9cc, 0xcf0c0dd5)},
+ {TOBN(0x7caaee8e, 0x4e9e8a50), TOBN(0x462e907b, 0x6269dafd),
+ TOBN(0x6ed5cee9, 0xfbe791c6), TOBN(0x68ca3259, 0xed430790)}},
+ {{TOBN(0x2b72bdf2, 0x13b5ba88), TOBN(0x60294c8a, 0x35ef0ac4),
+ TOBN(0x9c3230ed, 0x19b99b08), TOBN(0x560fff17, 0x6c2589aa)},
+ {TOBN(0x552b8487, 0xd6770374), TOBN(0xa373202d, 0x9a56f685),
+ TOBN(0xd3e7f907, 0x45f175d9), TOBN(0x3c2f315f, 0xd080d810)}},
+ {{TOBN(0x1130e9dd, 0x7b9520e8), TOBN(0xc078f9e2, 0x0af037b5),
+ TOBN(0x38cd2ec7, 0x1e9c104c), TOBN(0x0f684368, 0xc472fe92)},
+ {TOBN(0xd3f1b5ed, 0x6247e7ef), TOBN(0xb32d33a9, 0x396dfe21),
+ TOBN(0x46f59cf4, 0x4a9aa2c2), TOBN(0x69cd5168, 0xff0f7e41)}},
+ {{TOBN(0x3f59da0f, 0x4b3234da), TOBN(0xcf0b0235, 0xb4579ebe),
+ TOBN(0x6d1cbb25, 0x6d2476c7), TOBN(0x4f0837e6, 0x9dc30f08)},
+ {TOBN(0x9a4075bb, 0x906f6e98), TOBN(0x253bb434, 0xc761e7d1),
+ TOBN(0xde2e645f, 0x6e73af10), TOBN(0xb89a4060, 0x0c5f131c)}},
+ {{TOBN(0xd12840c5, 0xb8cc037f), TOBN(0x3d093a5b, 0x7405bb47),
+ TOBN(0x6202c253, 0x206348b8), TOBN(0xbf5d57fc, 0xc55a3ca7)},
+ {TOBN(0x89f6c90c, 0x8c3bef48), TOBN(0x23ac7623, 0x5a0a960a),
+ TOBN(0xdfbd3d6b, 0x552b42ab), TOBN(0x3ef22458, 0x132061f6)}},
+ {{TOBN(0xd74e9bda, 0xc97e6516), TOBN(0x88779360, 0xc230f49e),
+ TOBN(0xa6ec1de3, 0x1e74ea49), TOBN(0x581dcee5, 0x3fb645a2)},
+ {TOBN(0xbaef2391, 0x8f483f14), TOBN(0x6d2dddfc, 0xd137d13b),
+ TOBN(0x54cde50e, 0xd2743a42), TOBN(0x89a34fc5, 0xe4d97e67)}},
+ {{TOBN(0x13f1f5b3, 0x12e08ce5), TOBN(0xa80540b8, 0xa7f0b2ca),
+ TOBN(0x854bcf77, 0x01982805), TOBN(0xb8653ffd, 0x233bea04)},
+ {TOBN(0x8e7b8787, 0x02b0b4c9), TOBN(0x2675261f, 0x9acb170a),
+ TOBN(0x061a9d90, 0x930c14e5), TOBN(0xb59b30e0, 0xdef0abea)}},
+ {{TOBN(0x1dc19ea6, 0x0200ec7d), TOBN(0xb6f4a3f9, 0x0bce132b),
+ TOBN(0xb8d5de90, 0xf13e27e0), TOBN(0xbaee5ef0, 0x1fade16f)},
+ {TOBN(0x6f406aaa, 0xe4c6cf38), TOBN(0xab4cfe06, 0xd1369815),
+ TOBN(0x0dcffe87, 0xefd550c6), TOBN(0x9d4f59c7, 0x75ff7d39)}},
+ {{TOBN(0xb02553b1, 0x51deb6ad), TOBN(0x812399a4, 0xb1877749),
+ TOBN(0xce90f71f, 0xca6006e1), TOBN(0xc32363a6, 0xb02b6e77)},
+ {TOBN(0x02284fbe, 0xdc36c64d), TOBN(0x86c81e31, 0xa7e1ae61),
+ TOBN(0x2576c7e5, 0xb909d94a), TOBN(0x8b6f7d02, 0x818b2bb0)}},
+ {{TOBN(0xeca3ed07, 0x56faa38a), TOBN(0xa3790e6c, 0x9305bb54),
+ TOBN(0xd784eeda, 0x7bc73061), TOBN(0xbd56d369, 0x6dd50614)},
+ {TOBN(0xd6575949, 0x229a8aa9), TOBN(0xdcca8f47, 0x4595ec28),
+ TOBN(0x814305c1, 0x06ab4fe6), TOBN(0xc8c39768, 0x24f43f16)}},
+ {{TOBN(0xe2a45f36, 0x523f2b36), TOBN(0x995c6493, 0x920d93bb),
+ TOBN(0xf8afdab7, 0x90f1632b), TOBN(0x79ebbecd, 0x1c295954)},
+ {TOBN(0xc7bb3ddb, 0x79592f48), TOBN(0x67216a7b, 0x5f88e998),
+ TOBN(0xd91f098b, 0xbc01193e), TOBN(0xf7d928a5, 0xb1db83fc)}},
+ {{TOBN(0x55e38417, 0xe991f600), TOBN(0x2a91113e, 0x2981a934),
+ TOBN(0xcbc9d648, 0x06b13bde), TOBN(0xb011b6ac, 0x0755ff44)},
+ {TOBN(0x6f4cb518, 0x045ec613), TOBN(0x522d2d31, 0xc2f5930a),
+ TOBN(0x5acae1af, 0x382e65de), TOBN(0x57643067, 0x27bc966f)}},
+ {{TOBN(0x5e12705d, 0x1c7193f0), TOBN(0xf0f32f47, 0x3be8858e),
+ TOBN(0x785c3d7d, 0x96c6dfc7), TOBN(0xd75b4a20, 0xbf31795d)},
+ {TOBN(0x91acf17b, 0x342659d4), TOBN(0xe596ea34, 0x44f0378f),
+ TOBN(0x4515708f, 0xce52129d), TOBN(0x17387e1e, 0x79f2f585)}},
+ {{TOBN(0x72cfd2e9, 0x49dee168), TOBN(0x1ae05223, 0x3e2af239),
+ TOBN(0x009e75be, 0x1d94066a), TOBN(0x6cca31c7, 0x38abf413)},
+ {TOBN(0xb50bd61d, 0x9bc49908), TOBN(0x4a9b4a8c, 0xf5e2bc1e),
+ TOBN(0xeb6cc5f7, 0x946f83ac), TOBN(0x27da93fc, 0xebffab28)}},
+ {{TOBN(0xea314c96, 0x4821c8c5), TOBN(0x8de49ded, 0xa83c15f4),
+ TOBN(0x7a64cf20, 0x7af33004), TOBN(0x45f1bfeb, 0xc9627e10)},
+ {TOBN(0x878b0626, 0x54b9df60), TOBN(0x5e4fdc3c, 0xa95c0b33),
+ TOBN(0xe54a37ca, 0xc2035d8e), TOBN(0x9087cda9, 0x80f20b8c)}},
+ {{TOBN(0x36f61c23, 0x8319ade4), TOBN(0x766f287a, 0xde8cfdf8),
+ TOBN(0x48821948, 0x346f3705), TOBN(0x49a7b853, 0x16e4f4a2)},
+ {TOBN(0xb9b3f8a7, 0x5cedadfd), TOBN(0x8f562815, 0x8db2a815),
+ TOBN(0xc0b7d554, 0x01f68f95), TOBN(0x12971e27, 0x688a208e)}},
+ {{TOBN(0xc9f8b696, 0xd0ff34fc), TOBN(0x20824de2, 0x1222718c),
+ TOBN(0x7213cf9f, 0x0c95284d), TOBN(0xe2ad741b, 0xdc158240)},
+ {TOBN(0x0ee3a6df, 0x54043ccf), TOBN(0x16ff479b, 0xd84412b3),
+ TOBN(0xf6c74ee0, 0xdfc98af0), TOBN(0xa78a169f, 0x52fcd2fb)}},
+ {{TOBN(0xd8ae8746, 0x99c930e9), TOBN(0x1d33e858, 0x49e117a5),
+ TOBN(0x7581fcb4, 0x6624759f), TOBN(0xde50644f, 0x5bedc01d)},
+ {TOBN(0xbeec5d00, 0xcaf3155e), TOBN(0x672d66ac, 0xbc73e75f),
+ TOBN(0x86b9d8c6, 0x270b01db), TOBN(0xd249ef83, 0x50f55b79)}},
+ {{TOBN(0x6131d6d4, 0x73978fe3), TOBN(0xcc4e4542, 0x754b00a1),
+ TOBN(0x4e05df05, 0x57dfcfe9), TOBN(0x94b29cdd, 0x51ef6bf0)},
+ {TOBN(0xe4530cff, 0x9bc7edf2), TOBN(0x8ac236fd, 0xd3da65f3),
+ TOBN(0x0faf7d5f, 0xc8eb0b48), TOBN(0x4d2de14c, 0x660eb039)}},
+ {{TOBN(0xc006bba7, 0x60430e54), TOBN(0x10a2d0d6, 0xda3289ab),
+ TOBN(0x9c037a5d, 0xd7979c59), TOBN(0x04d1f3d3, 0xa116d944)},
+ {TOBN(0x9ff22473, 0x8a0983cd), TOBN(0x28e25b38, 0xc883cabb),
+ TOBN(0xe968dba5, 0x47a58995), TOBN(0x2c80b505, 0x774eebdf)}},
+ {{TOBN(0xee763b71, 0x4a953beb), TOBN(0x502e223f, 0x1642e7f6),
+ TOBN(0x6fe4b641, 0x61d5e722), TOBN(0x9d37c5b0, 0xdbef5316)},
+ {TOBN(0x0115ed70, 0xf8330bc7), TOBN(0x139850e6, 0x75a72789),
+ TOBN(0x27d7faec, 0xffceccc2), TOBN(0x3016a860, 0x4fd9f7f6)}},
+ {{TOBN(0xc492ec64, 0x4cd8f64c), TOBN(0x58a2d790, 0x279d7b51),
+ TOBN(0x0ced1fc5, 0x1fc75256), TOBN(0x3e658aed, 0x8f433017)},
+ {TOBN(0x0b61942e, 0x05da59eb), TOBN(0xba3d60a3, 0x0ddc3722),
+ TOBN(0x7c311cd1, 0x742e7f87), TOBN(0x6473ffee, 0xf6b01b6e)}}},
+ {{{TOBN(0x8303604f, 0x692ac542), TOBN(0xf079ffe1, 0x227b91d3),
+ TOBN(0x19f63e63, 0x15aaf9bd), TOBN(0xf99ee565, 0xf1f344fb)},
+ {TOBN(0x8a1d661f, 0xd6219199), TOBN(0x8c883bc6, 0xd48ce41c),
+ TOBN(0x1065118f, 0x3c74d904), TOBN(0x713889ee, 0x0faf8b1b)}},
+ {{TOBN(0x972b3f8f, 0x81a1b3be), TOBN(0x4f3ce145, 0xce2764a0),
+ TOBN(0xe2d0f1cc, 0x28c4f5f7), TOBN(0xdeee0c0d, 0xc7f3985b)},
+ {TOBN(0x7df4adc0, 0xd39e25c3), TOBN(0x40619820, 0xc467a080),
+ TOBN(0x440ebc93, 0x61cf5a58), TOBN(0x527729a6, 0x422ad600)}},
+ {{TOBN(0xca6c0937, 0xb1b76ba6), TOBN(0x1a2eab85, 0x4d2026dc),
+ TOBN(0xb1715e15, 0x19d9ae0a), TOBN(0xf1ad9199, 0xbac4a026)},
+ {TOBN(0x35b3dfb8, 0x07ea7b0e), TOBN(0xedf5496f, 0x3ed9eb89),
+ TOBN(0x8932e5ff, 0x2d6d08ab), TOBN(0xf314874e, 0x25bd2731)}},
+ {{TOBN(0xefb26a75, 0x3f73f449), TOBN(0x1d1c94f8, 0x8d44fc79),
+ TOBN(0x49f0fbc5, 0x3bc0dc4d), TOBN(0xb747ea0b, 0x3698a0d0)},
+ {TOBN(0x5218c3fe, 0x228d291e), TOBN(0x35b804b5, 0x43c129d6),
+ TOBN(0xfac859b8, 0xd1acc516), TOBN(0x6c10697d, 0x95d6e668)}},
+ {{TOBN(0xc38e438f, 0x0876fd4e), TOBN(0x45f0c307, 0x83d2f383),
+ TOBN(0x203cc2ec, 0xb10934cb), TOBN(0x6a8f2439, 0x2c9d46ee)},
+ {TOBN(0xf16b431b, 0x65ccde7b), TOBN(0x41e2cd18, 0x27e76a6f),
+ TOBN(0xb9c8cf8f, 0x4e3484d7), TOBN(0x64426efd, 0x8315244a)}},
+ {{TOBN(0x1c0a8e44, 0xfc94dea3), TOBN(0x34c8cdbf, 0xdad6a0b0),
+ TOBN(0x919c3840, 0x04113cef), TOBN(0xfd32fba4, 0x15490ffa)},
+ {TOBN(0x58d190f6, 0x795dcfb7), TOBN(0xfef01b03, 0x83588baf),
+ TOBN(0x9e6d1d63, 0xca1fc1c0), TOBN(0x53173f96, 0xf0a41ac9)}},
+ {{TOBN(0x2b1d402a, 0xba16f73b), TOBN(0x2fb31014, 0x8cf9b9fc),
+ TOBN(0x2d51e60e, 0x446ef7bf), TOBN(0xc731021b, 0xb91e1745)},
+ {TOBN(0x9d3b4724, 0x4fee99d4), TOBN(0x4bca48b6, 0xfac5c1ea),
+ TOBN(0x70f5f514, 0xbbea9af7), TOBN(0x751f55a5, 0x974c283a)}},
+ {{TOBN(0x6e30251a, 0xcb452fdb), TOBN(0x31ee6965, 0x50f30650),
+ TOBN(0xb0b3e508, 0x933548d9), TOBN(0xb8949a4f, 0xf4b0ef5b)},
+ {TOBN(0x208b8326, 0x3c88f3bd), TOBN(0xab147c30, 0xdb1d9989),
+ TOBN(0xed6515fd, 0x44d4df03), TOBN(0x17a12f75, 0xe72eb0c5)}},
+ {{TOBN(0x3b59796d, 0x36cf69db), TOBN(0x1219eee9, 0x56670c18),
+ TOBN(0xfe3341f7, 0x7a070d8e), TOBN(0x9b70130b, 0xa327f90c)},
+ {TOBN(0x36a32462, 0x0ae18e0e), TOBN(0x2021a623, 0x46c0a638),
+ TOBN(0x251b5817, 0xc62eb0d4), TOBN(0x87bfbcdf, 0x4c762293)}},
+ {{TOBN(0xf78ab505, 0xcdd61d64), TOBN(0x8c7a53fc, 0xc8c18857),
+ TOBN(0xa653ce6f, 0x16147515), TOBN(0x9c923aa5, 0xea7d52d5)},
+ {TOBN(0xc24709cb, 0x5c18871f), TOBN(0x7d53bec8, 0x73b3cc74),
+ TOBN(0x59264aff, 0xfdd1d4c4), TOBN(0x5555917e, 0x240da582)}},
+ {{TOBN(0xcae8bbda, 0x548f5a0e), TOBN(0x1910eaba, 0x3bbfbbe1),
+ TOBN(0xae579685, 0x7677afc3), TOBN(0x49ea61f1, 0x73ff0b5c)},
+ {TOBN(0x78655478, 0x4f7c3922), TOBN(0x95d337cd, 0x20c68eef),
+ TOBN(0x68f1e1e5, 0xdf779ab9), TOBN(0x14b491b0, 0xb5cf69a8)}},
+ {{TOBN(0x7a6cbbe0, 0x28e3fe89), TOBN(0xe7e1fee4, 0xc5aac0eb),
+ TOBN(0x7f47eda5, 0x697e5140), TOBN(0x4f450137, 0xb454921f)},
+ {TOBN(0xdb625f84, 0x95cd8185), TOBN(0x74be0ba1, 0xcdb2e583),
+ TOBN(0xaee4fd7c, 0xdd5e6de4), TOBN(0x4251437d, 0xe8101739)}},
+ {{TOBN(0x686d72a0, 0xac620366), TOBN(0x4be3fb9c, 0xb6d59344),
+ TOBN(0x6e8b44e7, 0xa1eb75b9), TOBN(0x84e39da3, 0x91a5c10c)},
+ {TOBN(0x37cc1490, 0xb38f0409), TOBN(0x02951943, 0x2c2ade82),
+ TOBN(0x9b688783, 0x1190a2d8), TOBN(0x25627d14, 0x231182ba)}},
+ {{TOBN(0x6eb550aa, 0x658a6d87), TOBN(0x1405aaa7, 0xcf9c7325),
+ TOBN(0xd147142e, 0x5c8748c9), TOBN(0x7f637e4f, 0x53ede0e0)},
+ {TOBN(0xf8ca2776, 0x14ffad2c), TOBN(0xe58fb1bd, 0xbafb6791),
+ TOBN(0x17158c23, 0xbf8f93fc), TOBN(0x7f15b373, 0x0a4a4655)}},
+ {{TOBN(0x39d4add2, 0xd842ca72), TOBN(0xa71e4391, 0x3ed96305),
+ TOBN(0x5bb09cbe, 0x6700be14), TOBN(0x68d69d54, 0xd8befcf6)},
+ {TOBN(0xa45f5367, 0x37183bcf), TOBN(0x7152b7bb, 0x3370dff7),
+ TOBN(0xcf887baa, 0xbf12525b), TOBN(0xe7ac7bdd, 0xd6d1e3cd)}},
+ {{TOBN(0x25914f78, 0x81fdad90), TOBN(0xcf638f56, 0x0d2cf6ab),
+ TOBN(0xb90bc03f, 0xcc054de5), TOBN(0x932811a7, 0x18b06350)},
+ {TOBN(0x2f00b330, 0x9bbd11ff), TOBN(0x76108a6f, 0xb4044974),
+ TOBN(0x801bb9e0, 0xa851d266), TOBN(0x0dd099be, 0xbf8990c1)}},
+ {{TOBN(0x58c5aaaa, 0xabe32986), TOBN(0x0fe9dd2a, 0x50d59c27),
+ TOBN(0x84951ff4, 0x8d307305), TOBN(0x6c23f829, 0x86529b78)},
+ {TOBN(0x50bb2218, 0x0b136a79), TOBN(0x7e2174de, 0x77a20996),
+ TOBN(0x6f00a4b9, 0xc0bb4da6), TOBN(0x89a25a17, 0xefdde8da)}},
+ {{TOBN(0xf728a27e, 0xc11ee01d), TOBN(0xf900553a, 0xe5f10dfb),
+ TOBN(0x189a83c8, 0x02ec893c), TOBN(0x3ca5bdc1, 0x23f66d77)},
+ {TOBN(0x98781537, 0x97eada9f), TOBN(0x59c50ab3, 0x10256230),
+ TOBN(0x346042d9, 0x323c69b3), TOBN(0x1b715a6d, 0x2c460449)}},
+ {{TOBN(0xa41dd476, 0x6ae06e0b), TOBN(0xcdd7888e, 0x9d42e25f),
+ TOBN(0x0f395f74, 0x56b25a20), TOBN(0xeadfe0ae, 0x8700e27e)},
+ {TOBN(0xb09d52a9, 0x69950093), TOBN(0x3525d9cb, 0x327f8d40),
+ TOBN(0xb8235a94, 0x67df886a), TOBN(0x77e4b0dd, 0x035faec2)}},
+ {{TOBN(0x115eb20a, 0x517d7061), TOBN(0x77fe3433, 0x6c2df683),
+ TOBN(0x6870ddc7, 0xcdc6fc67), TOBN(0xb1610588, 0x0b87de83)},
+ {TOBN(0x343584ca, 0xd9c4ddbe), TOBN(0xb3164f1c, 0x3d754be2),
+ TOBN(0x0731ed3a, 0xc1e6c894), TOBN(0x26327dec, 0x4f6b904c)}},
+ {{TOBN(0x9d49c6de, 0x97b5cd32), TOBN(0x40835dae, 0xb5eceecd),
+ TOBN(0xc66350ed, 0xd9ded7fe), TOBN(0x8aeebb5c, 0x7a678804)},
+ {TOBN(0x51d42fb7, 0x5b8ee9ec), TOBN(0xd7a17bdd, 0x8e3ca118),
+ TOBN(0x40d7511a, 0x2ef4400e), TOBN(0xc48990ac, 0x875a66f4)}},
+ {{TOBN(0x8de07d2a, 0x2199e347), TOBN(0xbee75556, 0x2a39e051),
+ TOBN(0x56918786, 0x916e51dc), TOBN(0xeb191313, 0x4a2d89ec)},
+ {TOBN(0x6679610d, 0x37d341ed), TOBN(0x434fbb41, 0x56d51c2b),
+ TOBN(0xe54b7ee7, 0xd7492dba), TOBN(0xaa33a79a, 0x59021493)}},
+ {{TOBN(0x49fc5054, 0xe4bd6d3d), TOBN(0x09540f04, 0x5ab551d0),
+ TOBN(0x8acc9085, 0x4942d3a6), TOBN(0x231af02f, 0x2d28323b)},
+ {TOBN(0x93458cac, 0x0992c163), TOBN(0x1fef8e71, 0x888e3bb4),
+ TOBN(0x27578da5, 0xbe8c268c), TOBN(0xcc8be792, 0xe805ec00)}},
+ {{TOBN(0x29267bae, 0xc61c3855), TOBN(0xebff429d, 0x58c1fd3b),
+ TOBN(0x22d886c0, 0x8c0b93b8), TOBN(0xca5e00b2, 0x2ddb8953)},
+ {TOBN(0xcf330117, 0xc3fed8b7), TOBN(0xd49ac6fa, 0x819c01f6),
+ TOBN(0x6ddaa6bd, 0x3c0fbd54), TOBN(0x91743068, 0x8049a2cf)}},
+ {{TOBN(0xd67f981e, 0xaff2ef81), TOBN(0xc3654d35, 0x2818ae80),
+ TOBN(0x81d05044, 0x1b2aa892), TOBN(0x2db067bf, 0x3d099328)},
+ {TOBN(0xe7c79e86, 0x703dcc97), TOBN(0xe66f9b37, 0xe133e215),
+ TOBN(0xcdf119a6, 0xe39a7a5c), TOBN(0x47c60de3, 0x876f1b61)}},
+ {{TOBN(0x6e405939, 0xd860f1b2), TOBN(0x3e9a1dbc, 0xf5ed4d4a),
+ TOBN(0x3f23619e, 0xc9b6bcbd), TOBN(0x5ee790cf, 0x734e4497)},
+ {TOBN(0xf0a834b1, 0x5bdaf9bb), TOBN(0x02cedda7, 0x4ca295f0),
+ TOBN(0x4619aa2b, 0xcb8e378c), TOBN(0xe5613244, 0xcc987ea4)}},
+ {{TOBN(0x0bc022cc, 0x76b23a50), TOBN(0x4a2793ad, 0x0a6c21ce),
+ TOBN(0x38328780, 0x89cac3f5), TOBN(0x29176f1b, 0xcba26d56)},
+ {TOBN(0x06296187, 0x4f6f59eb), TOBN(0x86e9bca9, 0x8bdc658e),
+ TOBN(0x2ca9c4d3, 0x57e30402), TOBN(0x5438b216, 0x516a09bb)}},
+ {{TOBN(0x0a6a063c, 0x7672765a), TOBN(0x37a3ce64, 0x0547b9bf),
+ TOBN(0x42c099c8, 0x98b1a633), TOBN(0xb5ab800d, 0x05ee6961)},
+ {TOBN(0xf1963f59, 0x11a5acd6), TOBN(0xbaee6157, 0x46201063),
+ TOBN(0x36d9a649, 0xa596210a), TOBN(0xaed04363, 0x1ba7138c)}},
+ {{TOBN(0xcf817d1c, 0xa4a82b76), TOBN(0x5586960e, 0xf3806be9),
+ TOBN(0x7ab67c89, 0x09dc6bb5), TOBN(0x52ace7a0, 0x114fe7eb)},
+ {TOBN(0xcd987618, 0xcbbc9b70), TOBN(0x4f06fd5a, 0x604ca5e1),
+ TOBN(0x90af14ca, 0x6dbde133), TOBN(0x1afe4322, 0x948a3264)}},
+ {{TOBN(0xa70d2ca6, 0xc44b2c6c), TOBN(0xab726799, 0x0ef87dfe),
+ TOBN(0x310f64dc, 0x2e696377), TOBN(0x49b42e68, 0x4c8126a0)},
+ {TOBN(0x0ea444c3, 0xcea0b176), TOBN(0x53a8ddf7, 0xcb269182),
+ TOBN(0xf3e674eb, 0xbbba9dcb), TOBN(0x0d2878a8, 0xd8669d33)}},
+ {{TOBN(0x04b935d5, 0xd019b6a3), TOBN(0xbb5cf88e, 0x406f1e46),
+ TOBN(0xa1912d16, 0x5b57c111), TOBN(0x9803fc21, 0x19ebfd78)},
+ {TOBN(0x4f231c9e, 0xc07764a9), TOBN(0xd93286ee, 0xb75bd055),
+ TOBN(0x83a9457d, 0x8ee6c9de), TOBN(0x04695915, 0x6087ec90)}},
+ {{TOBN(0x14c6dd8a, 0x58d6cd46), TOBN(0x9cb633b5, 0x8e6634d2),
+ TOBN(0xc1305047, 0xf81bc328), TOBN(0x12ede0e2, 0x26a177e5)},
+ {TOBN(0x332cca62, 0x065a6f4f), TOBN(0xc3a47ecd, 0x67be487b),
+ TOBN(0x741eb187, 0x0f47ed1c), TOBN(0x99e66e58, 0xe7598b14)}},
+ {{TOBN(0x6f0544ca, 0x63d0ff12), TOBN(0xe5efc784, 0xb610a05f),
+ TOBN(0xf72917b1, 0x7cad7b47), TOBN(0x3ff6ea20, 0xf2cac0c0)},
+ {TOBN(0xcc23791b, 0xf21db8b7), TOBN(0x7dac70b1, 0xd7d93565),
+ TOBN(0x682cda1d, 0x694bdaad), TOBN(0xeb88bb8c, 0x1023516d)}},
+ {{TOBN(0xc4c634b4, 0xdfdbeb1b), TOBN(0x22f5ca72, 0xb4ee4dea),
+ TOBN(0x1045a368, 0xe6524821), TOBN(0xed9e8a3f, 0x052b18b2)},
+ {TOBN(0x9b7f2cb1, 0xb961f49a), TOBN(0x7fee2ec1, 0x7b009670),
+ TOBN(0x350d8754, 0x22507a6d), TOBN(0x561bd711, 0x4db55f1d)}},
+ {{TOBN(0x4c189ccc, 0x320bbcaf), TOBN(0x568434cf, 0xdf1de48c),
+ TOBN(0x6af1b00e, 0x0fa8f128), TOBN(0xf0ba9d02, 0x8907583c)},
+ {TOBN(0x735a4004, 0x32ff9f60), TOBN(0x3dd8e4b6, 0xc25dcf33),
+ TOBN(0xf2230f16, 0x42c74cef), TOBN(0xd8117623, 0x013fa8ad)}},
+ {{TOBN(0x36822876, 0xf51fe76e), TOBN(0x8a6811cc, 0x11d62589),
+ TOBN(0xc3fc7e65, 0x46225718), TOBN(0xb7df2c9f, 0xc82fdbcd)},
+ {TOBN(0x3b1d4e52, 0xdd7b205b), TOBN(0xb6959478, 0x47a2e414),
+ TOBN(0x05e4d793, 0xefa91148), TOBN(0xb47ed446, 0xfd2e9675)}},
+ {{TOBN(0x1a7098b9, 0x04c9d9bf), TOBN(0x661e2881, 0x1b793048),
+ TOBN(0xb1a16966, 0xb01ee461), TOBN(0xbc521308, 0x2954746f)},
+ {TOBN(0xc909a0fc, 0x2477de50), TOBN(0xd80bb41c, 0x7dbd51ef),
+ TOBN(0xa85be7ec, 0x53294905), TOBN(0x6d465b18, 0x83958f97)}},
+ {{TOBN(0x16f6f330, 0xfb6840fd), TOBN(0xfaaeb214, 0x3401e6c8),
+ TOBN(0xaf83d30f, 0xccb5b4f8), TOBN(0x22885739, 0x266dec4b)},
+ {TOBN(0x51b4367c, 0x7bc467df), TOBN(0x926562e3, 0xd842d27a),
+ TOBN(0xdfcb6614, 0x0fea14a6), TOBN(0xeb394dae, 0xf2734cd9)}},
+ {{TOBN(0x3eeae5d2, 0x11c0be98), TOBN(0xb1e6ed11, 0x814e8165),
+ TOBN(0x191086bc, 0xe52bce1c), TOBN(0x14b74cc6, 0xa75a04da)},
+ {TOBN(0x63cf1186, 0x8c060985), TOBN(0x071047de, 0x2dbd7f7c),
+ TOBN(0x4e433b8b, 0xce0942ca), TOBN(0xecbac447, 0xd8fec61d)}},
+ {{TOBN(0x8f0ed0e2, 0xebf3232f), TOBN(0xfff80f9e, 0xc52a2edd),
+ TOBN(0xad9ab433, 0x75b55fdb), TOBN(0x73ca7820, 0xe42e0c11)},
+ {TOBN(0x6dace0a0, 0xe6251b46), TOBN(0x89bc6b5c, 0x4c0d932d),
+ TOBN(0x3438cd77, 0x095da19a), TOBN(0x2f24a939, 0x8d48bdfb)}},
+ {{TOBN(0x99b47e46, 0x766561b7), TOBN(0x736600e6, 0x0ed0322a),
+ TOBN(0x06a47cb1, 0x638e1865), TOBN(0x927c1c2d, 0xcb136000)},
+ {TOBN(0x29542337, 0x0cc5df69), TOBN(0x99b37c02, 0x09d649a9),
+ TOBN(0xc5f0043c, 0x6aefdb27), TOBN(0x6cdd9987, 0x1be95c27)}},
+ {{TOBN(0x69850931, 0x390420d2), TOBN(0x299c40ac, 0x0983efa4),
+ TOBN(0x3a05e778, 0xaf39aead), TOBN(0x84274408, 0x43a45193)},
+ {TOBN(0x6bcd0fb9, 0x91a711a0), TOBN(0x461592c8, 0x9f52ab17),
+ TOBN(0xb49302b4, 0xda3c6ed6), TOBN(0xc51fddc7, 0x330d7067)}},
+ {{TOBN(0x94babeb6, 0xda50d531), TOBN(0x521b840d, 0xa6a7b9da),
+ TOBN(0x5305151e, 0x404bdc89), TOBN(0x1bcde201, 0xd0d07449)},
+ {TOBN(0xf427a78b, 0x3b76a59a), TOBN(0xf84841ce, 0x07791a1b),
+ TOBN(0xebd314be, 0xbf91ed1c), TOBN(0x8e61d34c, 0xbf172943)}},
+ {{TOBN(0x1d5dc451, 0x5541b892), TOBN(0xb186ee41, 0xfc9d9e54),
+ TOBN(0x9d9f345e, 0xd5bf610d), TOBN(0x3e7ba65d, 0xf6acca9f)},
+ {TOBN(0x9dda787a, 0xa8369486), TOBN(0x09f9dab7, 0x8eb5ba53),
+ TOBN(0x5afb2033, 0xd6481bc3), TOBN(0x76f4ce30, 0xafa62104)}},
+ {{TOBN(0xa8fa00cf, 0xf4f066b5), TOBN(0x89ab5143, 0x461dafc2),
+ TOBN(0x44339ed7, 0xa3389998), TOBN(0x2ff862f1, 0xbc214903)},
+ {TOBN(0x2c88f985, 0xb05556e3), TOBN(0xcd96058e, 0x3467081e),
+ TOBN(0x7d6a4176, 0xedc637ea), TOBN(0xe1743d09, 0x36a5acdc)}},
+ {{TOBN(0x66fd72e2, 0x7eb37726), TOBN(0xf7fa264e, 0x1481a037),
+ TOBN(0x9fbd3bde, 0x45f4aa79), TOBN(0xed1e0147, 0x767c3e22)},
+ {TOBN(0x7621f979, 0x82e7abe2), TOBN(0x19eedc72, 0x45f633f8),
+ TOBN(0xe69b155e, 0x6137bf3a), TOBN(0xa0ad13ce, 0x414ee94e)}},
+ {{TOBN(0x93e3d524, 0x1c0e651a), TOBN(0xab1a6e2a, 0x02ce227e),
+ TOBN(0xe7af1797, 0x4ab27eca), TOBN(0x245446de, 0xbd444f39)},
+ {TOBN(0x59e22a21, 0x56c07613), TOBN(0x43deafce, 0xf4275498),
+ TOBN(0x10834ccb, 0x67fd0946), TOBN(0xa75841e5, 0x47406edf)}},
+ {{TOBN(0xebd6a677, 0x7b0ac93d), TOBN(0xa6e37b0d, 0x78f5e0d7),
+ TOBN(0x2516c096, 0x76f5492b), TOBN(0x1e4bf888, 0x9ac05f3a)},
+ {TOBN(0xcdb42ce0, 0x4df0ba2b), TOBN(0x935d5cfd, 0x5062341b),
+ TOBN(0x8a303333, 0x82acac20), TOBN(0x429438c4, 0x5198b00e)}},
+ {{TOBN(0x1d083bc9, 0x049d33fa), TOBN(0x58b82dda, 0x946f67ff),
+ TOBN(0xac3e2db8, 0x67a1d6a3), TOBN(0x62e6bead, 0x1798aac8)},
+ {TOBN(0xfc85980f, 0xde46c58c), TOBN(0xa7f69379, 0x69c8d7be),
+ TOBN(0x23557927, 0x837b35ec), TOBN(0x06a933d8, 0xe0790c0c)}},
+ {{TOBN(0x827c0e9b, 0x077ff55d), TOBN(0x53977798, 0xbb26e680),
+ TOBN(0x59530874, 0x1d9cb54f), TOBN(0xcca3f449, 0x4aac53ef)},
+ {TOBN(0x11dc5c87, 0xa07eda0f), TOBN(0xc138bccf, 0xfd6400c8),
+ TOBN(0x549680d3, 0x13e5da72), TOBN(0xc93eed82, 0x4540617e)}},
+ {{TOBN(0xfd3db157, 0x4d0b75c0), TOBN(0x9716eb42, 0x6386075b),
+ TOBN(0x0639605c, 0x817b2c16), TOBN(0x09915109, 0xf1e4f201)},
+ {TOBN(0x35c9a928, 0x5cca6c3b), TOBN(0xb25f7d1a, 0x3505c900),
+ TOBN(0xeb9f7d20, 0x630480c4), TOBN(0xc3c7b8c6, 0x2a1a501c)}},
+ {{TOBN(0x3f99183c, 0x5a1f8e24), TOBN(0xfdb118fa, 0x9dd255f0),
+ TOBN(0xb9b18b90, 0xc27f62a6), TOBN(0xe8f732f7, 0x396ec191)},
+ {TOBN(0x524a2d91, 0x0be786ab), TOBN(0x5d32adef, 0x0ac5a0f5),
+ TOBN(0x9b53d4d6, 0x9725f694), TOBN(0x032a76c6, 0x0510ba89)}},
+ {{TOBN(0x840391a3, 0xebeb1544), TOBN(0x44b7b88c, 0x3ed73ac3),
+ TOBN(0xd24bae7a, 0x256cb8b3), TOBN(0x7ceb151a, 0xe394cb12)},
+ {TOBN(0xbd6b66d0, 0x5bc1e6a8), TOBN(0xec70cecb, 0x090f07bf),
+ TOBN(0x270644ed, 0x7d937589), TOBN(0xee9e1a3d, 0x5f1dccfe)}},
+ {{TOBN(0xb0d40a84, 0x745b98d2), TOBN(0xda429a21, 0x2556ed40),
+ TOBN(0xf676eced, 0x85148cb9), TOBN(0x5a22d40c, 0xded18936)},
+ {TOBN(0x3bc4b9e5, 0x70e8a4ce), TOBN(0xbfd1445b, 0x9eae0379),
+ TOBN(0xf23f2c0c, 0x1a0bd47e), TOBN(0xa9c0bb31, 0xe1845531)}},
+ {{TOBN(0x9ddc4d60, 0x0a4c3f6b), TOBN(0xbdfaad79, 0x2c15ef44),
+ TOBN(0xce55a236, 0x7f484acc), TOBN(0x08653ca7, 0x055b1f15)},
+ {TOBN(0x2efa8724, 0x538873a3), TOBN(0x09299e5d, 0xace1c7e7),
+ TOBN(0x07afab66, 0xade332ba), TOBN(0x9be1fdf6, 0x92dd71b7)}},
+ {{TOBN(0xa49b5d59, 0x5758b11c), TOBN(0x0b852893, 0xc8654f40),
+ TOBN(0xb63ef6f4, 0x52379447), TOBN(0xd4957d29, 0x105e690c)},
+ {TOBN(0x7d484363, 0x646559b0), TOBN(0xf4a8273c, 0x49788a8e),
+ TOBN(0xee406cb8, 0x34ce54a9), TOBN(0x1e1c260f, 0xf86fda9b)}},
+ {{TOBN(0xe150e228, 0xcf6a4a81), TOBN(0x1fa3b6a3, 0x1b488772),
+ TOBN(0x1e6ff110, 0xc5a9c15b), TOBN(0xc6133b91, 0x8ad6aa47)},
+ {TOBN(0x8ac5d55c, 0x9dffa978), TOBN(0xba1d1c1d, 0x5f3965f2),
+ TOBN(0xf969f4e0, 0x7732b52f), TOBN(0xfceecdb5, 0xa5172a07)}},
+ {{TOBN(0xb0120a5f, 0x10f2b8f5), TOBN(0xc83a6cdf, 0x5c4c2f63),
+ TOBN(0x4d47a491, 0xf8f9c213), TOBN(0xd9e1cce5, 0xd3f1bbd5)},
+ {TOBN(0x0d91bc7c, 0xaba7e372), TOBN(0xfcdc74c8, 0xdfd1a2db),
+ TOBN(0x05efa800, 0x374618e5), TOBN(0x11216969, 0x15a7925e)}},
+ {{TOBN(0xd4c89823, 0xf6021c5d), TOBN(0x880d5e84, 0xeff14423),
+ TOBN(0x6523bc5a, 0x6dcd1396), TOBN(0xd1acfdfc, 0x113c978b)},
+ {TOBN(0xb0c164e8, 0xbbb66840), TOBN(0xf7f4301e, 0x72b58459),
+ TOBN(0xc29ad4a6, 0xa638e8ec), TOBN(0xf5ab8961, 0x46b78699)}},
+ {{TOBN(0x9dbd7974, 0x0e954750), TOBN(0x0121de88, 0x64f9d2c6),
+ TOBN(0x2e597b42, 0xd985232e), TOBN(0x55b6c3c5, 0x53451777)},
+ {TOBN(0xbb53e547, 0x519cb9fb), TOBN(0xf134019f, 0x8428600d),
+ TOBN(0x5a473176, 0xe081791a), TOBN(0x2f3e2263, 0x35fb0c08)}},
+ {{TOBN(0xb28c3017, 0x73d273b0), TOBN(0xccd21076, 0x7721ef9a),
+ TOBN(0x054cc292, 0xb650dc39), TOBN(0x662246de, 0x6188045e)},
+ {TOBN(0x904b52fa, 0x6b83c0d1), TOBN(0xa72df267, 0x97e9cd46),
+ TOBN(0x886b43cd, 0x899725e4), TOBN(0x2b651688, 0xd849ff22)}},
+ {{TOBN(0x60479b79, 0x02f34533), TOBN(0x5e354c14, 0x0c77c148),
+ TOBN(0xb4bb7581, 0xa8537c78), TOBN(0x188043d7, 0xefe1495f)},
+ {TOBN(0x9ba12f42, 0x8c1d5026), TOBN(0x2e0c8a26, 0x93d4aaab),
+ TOBN(0xbdba7b8b, 0xaa57c450), TOBN(0x140c9ad6, 0x9bbdafef)}},
+ {{TOBN(0x2067aa42, 0x25ac0f18), TOBN(0xf7b1295b, 0x04d1fbf3),
+ TOBN(0x14829111, 0xa4b04824), TOBN(0x2ce3f192, 0x33bd5e91)},
+ {TOBN(0x9c7a1d55, 0x8f2e1b72), TOBN(0xfe932286, 0x302aa243),
+ TOBN(0x497ca7b4, 0xd4be9554), TOBN(0xb8e821b8, 0xe0547a6e)}},
+ {{TOBN(0xfb2838be, 0x67e573e0), TOBN(0x05891db9, 0x4084c44b),
+ TOBN(0x91311373, 0x96c1c2c5), TOBN(0x6aebfa3f, 0xd958444b)},
+ {TOBN(0xac9cdce9, 0xe56e55c1), TOBN(0x7148ced3, 0x2caa46d0),
+ TOBN(0x2e10c7ef, 0xb61fe8eb), TOBN(0x9fd835da, 0xff97cf4d)}}},
+ {{{TOBN(0xa36da109, 0x081e9387), TOBN(0xfb9780d7, 0x8c935828),
+ TOBN(0xd5940332, 0xe540b015), TOBN(0xc9d7b51b, 0xe0f466fa)},
+ {TOBN(0xfaadcd41, 0xd6d9f671), TOBN(0xba6c1e28, 0xb1a2ac17),
+ TOBN(0x066a7833, 0xed201e5f), TOBN(0x19d99719, 0xf90f462b)}},
+ {{TOBN(0xf431f462, 0x060b5f61), TOBN(0xa56f46b4, 0x7bd057c2),
+ TOBN(0x348dca6c, 0x47e1bf65), TOBN(0x9a38783e, 0x41bcf1ff)},
+ {TOBN(0x7a5d33a9, 0xda710718), TOBN(0x5a779987, 0x2e0aeaf6),
+ TOBN(0xca87314d, 0x2d29d187), TOBN(0xfa0edc3e, 0xc687d733)}},
+ {{TOBN(0x9df33621, 0x6a31e09b), TOBN(0xde89e44d, 0xc1350e35),
+ TOBN(0x29214871, 0x4ca0cf52), TOBN(0xdf379672, 0x0b88a538)},
+ {TOBN(0xc92a510a, 0x2591d61b), TOBN(0x79aa87d7, 0x585b447b),
+ TOBN(0xf67db604, 0xe5287f77), TOBN(0x1697c8bf, 0x5efe7a80)}},
+ {{TOBN(0x1c894849, 0xcb198ac7), TOBN(0xa884a93d, 0x0f264665),
+ TOBN(0x2da964ef, 0x9b200678), TOBN(0x3c351b87, 0x009834e6)},
+ {TOBN(0xafb2ef9f, 0xe2c4b44b), TOBN(0x580f6c47, 0x3326790c),
+ TOBN(0xb8480521, 0x0b02264a), TOBN(0x8ba6f9e2, 0x42a194e2)}},
+ {{TOBN(0xfc87975f, 0x8fb54738), TOBN(0x35160788, 0x27c3ead3),
+ TOBN(0x834116d2, 0xb74a085a), TOBN(0x53c99a73, 0xa62fe996)},
+ {TOBN(0x87585be0, 0x5b81c51b), TOBN(0x925bafa8, 0xbe0852b7),
+ TOBN(0x76a4fafd, 0xa84d19a7), TOBN(0x39a45982, 0x585206d4)}},
+ {{TOBN(0x499b6ab6, 0x5eb03c0e), TOBN(0xf19b7954, 0x72bc3fde),
+ TOBN(0xa86b5b9c, 0x6e3a80d2), TOBN(0xe4377508, 0x6d42819f)},
+ {TOBN(0xc1663650, 0xbb3ee8a3), TOBN(0x75eb14fc, 0xb132075f),
+ TOBN(0xa8ccc906, 0x7ad834f6), TOBN(0xea6a2474, 0xe6e92ffd)}},
+ {{TOBN(0x9d72fd95, 0x0f8d6758), TOBN(0xcb84e101, 0x408c07dd),
+ TOBN(0xb9114bfd, 0xa5e23221), TOBN(0x358b5fe2, 0xe94e742c)},
+ {TOBN(0x1c0577ec, 0x95f40e75), TOBN(0xf0155451, 0x3d73f3d6),
+ TOBN(0x9d55cd67, 0xbd1b9b66), TOBN(0x63e86e78, 0xaf8d63c7)}},
+ {{TOBN(0x39d934ab, 0xd3c095f1), TOBN(0x04b261be, 0xe4b76d71),
+ TOBN(0x1d2e6970, 0xe73e6984), TOBN(0x879fb23b, 0x5e5fcb11)},
+ {TOBN(0x11506c72, 0xdfd75490), TOBN(0x3a97d085, 0x61bcf1c1),
+ TOBN(0x43201d82, 0xbf5e7007), TOBN(0x7f0ac52f, 0x798232a7)}},
+ {{TOBN(0x2715cbc4, 0x6eb564d4), TOBN(0x8d6c752c, 0x9e570e29),
+ TOBN(0xf80247c8, 0x9ef5fd5d), TOBN(0xc3c66b46, 0xd53eb514)},
+ {TOBN(0x9666b401, 0x0f87de56), TOBN(0xce62c06f, 0xc6c603b5),
+ TOBN(0xae7b4c60, 0x7e4fc942), TOBN(0x38ac0b77, 0x663a9c19)}},
+ {{TOBN(0xcb4d20ee, 0x4b049136), TOBN(0x8b63bf12, 0x356a4613),
+ TOBN(0x1221aef6, 0x70e08128), TOBN(0xe62d8c51, 0x4acb6b16)},
+ {TOBN(0x71f64a67, 0x379e7896), TOBN(0xb25237a2, 0xcafd7fa5),
+ TOBN(0xf077bd98, 0x3841ba6a), TOBN(0xc4ac0244, 0x3cd16e7e)}},
+ {{TOBN(0x548ba869, 0x21fea4ca), TOBN(0xd36d0817, 0xf3dfdac1),
+ TOBN(0x09d8d71f, 0xf4685faf), TOBN(0x8eff66be, 0xc52c459a)},
+ {TOBN(0x182faee7, 0x0b57235e), TOBN(0xee3c39b1, 0x0106712b),
+ TOBN(0x5107331f, 0xc0fcdcb0), TOBN(0x669fb9dc, 0xa51054ba)}},
+ {{TOBN(0xb25101fb, 0x319d7682), TOBN(0xb0293129, 0x0a982fee),
+ TOBN(0x51c1c9b9, 0x0261b344), TOBN(0x0e008c5b, 0xbfd371fa)},
+ {TOBN(0xd866dd1c, 0x0278ca33), TOBN(0x666f76a6, 0xe5aa53b1),
+ TOBN(0xe5cfb779, 0x6013a2cf), TOBN(0x1d3a1aad, 0xa3521836)}},
+ {{TOBN(0xcedd2531, 0x73faa485), TOBN(0xc8ee6c4f, 0xc0a76878),
+ TOBN(0xddbccfc9, 0x2a11667d), TOBN(0x1a418ea9, 0x1c2f695a)},
+ {TOBN(0xdb11bd92, 0x51f73971), TOBN(0x3e4b3c82, 0xda2ed89f),
+ TOBN(0x9a44f3f4, 0xe73e0319), TOBN(0xd1e3de0f, 0x303431af)}},
+ {{TOBN(0x3c5604ff, 0x50f75f9c), TOBN(0x1d8eddf3, 0x7e752b22),
+ TOBN(0x0ef074dd, 0x3c9a1118), TOBN(0xd0ffc172, 0xccb86d7b)},
+ {TOBN(0xabd1ece3, 0x037d90f2), TOBN(0xe3f307d6, 0x6055856c),
+ TOBN(0x422f9328, 0x7e4c6daf), TOBN(0x902aac66, 0x334879a0)}},
+ {{TOBN(0xb6a1e7bf, 0x94cdfade), TOBN(0x6c97e1ed, 0x7fc6d634),
+ TOBN(0x662ad24d, 0xa2fb63f8), TOBN(0xf81be1b9, 0xa5928405)},
+ {TOBN(0x86d765e4, 0xd14b4206), TOBN(0xbecc2e0e, 0x8fa0db65),
+ TOBN(0xa28838e0, 0xb17fc76c), TOBN(0xe49a602a, 0xe37cf24e)}},
+ {{TOBN(0x76b4131a, 0x567193ec), TOBN(0xaf3c305a, 0xe5f6e70b),
+ TOBN(0x9587bd39, 0x031eebdd), TOBN(0x5709def8, 0x71bbe831)},
+ {TOBN(0x57059983, 0x0eb2b669), TOBN(0x4d80ce1b, 0x875b7029),
+ TOBN(0x838a7da8, 0x0364ac16), TOBN(0x2f431d23, 0xbe1c83ab)}},
+ {{TOBN(0xe56812a6, 0xf9294dd3), TOBN(0xb448d01f, 0x9b4b0d77),
+ TOBN(0xf3ae6061, 0x04e8305c), TOBN(0x2bead645, 0x94d8c63e)},
+ {TOBN(0x0a85434d, 0x84fd8b07), TOBN(0x537b983f, 0xf7a9dee5),
+ TOBN(0xedcc5f18, 0xef55bd85), TOBN(0x2041af62, 0x21c6cf8b)}},
+ {{TOBN(0x8e52874c, 0xb940c71e), TOBN(0x211935a9, 0xdb5f4b3a),
+ TOBN(0x94350492, 0x301b1dc3), TOBN(0x33d2646d, 0x29958620)},
+ {TOBN(0x16b0d64b, 0xef911404), TOBN(0x9d1f25ea, 0x9a3c5ef4),
+ TOBN(0x20f200eb, 0x4a352c78), TOBN(0x43929f2c, 0x4bd0b428)}},
+ {{TOBN(0xa5656667, 0xc7196e29), TOBN(0x7992c2f0, 0x9391be48),
+ TOBN(0xaaa97cbd, 0x9ee0cd6e), TOBN(0x51b0310c, 0x3dc8c9bf)},
+ {TOBN(0x237f8acf, 0xdd9f22cb), TOBN(0xbb1d81a1, 0xb585d584),
+ TOBN(0x8d5d85f5, 0x8c416388), TOBN(0x0d6e5a5a, 0x42fe474f)}},
+ {{TOBN(0xe7812766, 0x38235d4e), TOBN(0x1c62bd67, 0x496e3298),
+ TOBN(0x8378660c, 0x3f175bc8), TOBN(0x4d04e189, 0x17afdd4d)},
+ {TOBN(0x32a81601, 0x85a8068c), TOBN(0xdb58e4e1, 0x92b29a85),
+ TOBN(0xe8a65b86, 0xc70d8a3b), TOBN(0x5f0e6f4e, 0x98a0403b)}},
+ {{TOBN(0x08129684, 0x69ed2370), TOBN(0x34dc30bd, 0x0871ee26),
+ TOBN(0x3a5ce948, 0x7c9c5b05), TOBN(0x7d487b80, 0x43a90c87)},
+ {TOBN(0x4089ba37, 0xdd0e7179), TOBN(0x45f80191, 0xb4041811),
+ TOBN(0x1c3e1058, 0x98747ba5), TOBN(0x98c4e13a, 0x6e1ae592)}},
+ {{TOBN(0xd44636e6, 0xe82c9f9e), TOBN(0x711db87c, 0xc33a1043),
+ TOBN(0x6f431263, 0xaa8aec05), TOBN(0x43ff120d, 0x2744a4aa)},
+ {TOBN(0xd3bd892f, 0xae77779b), TOBN(0xf0fe0cc9, 0x8cdc9f82),
+ TOBN(0xca5f7fe6, 0xf1c5b1bc), TOBN(0xcc63a682, 0x44929a72)}},
+ {{TOBN(0xc7eaba0c, 0x09dbe19a), TOBN(0x2f3585ad, 0x6b5c73c2),
+ TOBN(0x8ab8924b, 0x0ae50c30), TOBN(0x17fcd27a, 0x638b30ba)},
+ {TOBN(0xaf414d34, 0x10b3d5a5), TOBN(0x09c107d2, 0x2a9accf1),
+ TOBN(0x15dac49f, 0x946a6242), TOBN(0xaec3df2a, 0xd707d642)}},
+ {{TOBN(0x2c2492b7, 0x3f894ae0), TOBN(0xf59df3e5, 0xb75f18ce),
+ TOBN(0x7cb740d2, 0x8f53cad0), TOBN(0x3eb585fb, 0xc4f01294)},
+ {TOBN(0x17da0c86, 0x32c7f717), TOBN(0xeb8c795b, 0xaf943f4c),
+ TOBN(0x4ee23fb5, 0xf67c51d2), TOBN(0xef187575, 0x68889949)}},
+ {{TOBN(0xa6b4bdb2, 0x0389168b), TOBN(0xc4ecd258, 0xea577d03),
+ TOBN(0x3a63782b, 0x55743082), TOBN(0x6f678f4c, 0xc72f08cd)},
+ {TOBN(0x553511cf, 0x65e58dd8), TOBN(0xd53b4e3e, 0xd402c0cd),
+ TOBN(0x37de3e29, 0xa037c14c), TOBN(0x86b6c516, 0xc05712aa)}},
+ {{TOBN(0x2834da3e, 0xb38dff6f), TOBN(0xbe012c52, 0xea636be8),
+ TOBN(0x292d238c, 0x61dd37f8), TOBN(0x0e54523f, 0x8f8142db)},
+ {TOBN(0xe31eb436, 0x036a05d8), TOBN(0x83e3cdff, 0x1e93c0ff),
+ TOBN(0x3fd2fe0f, 0x50821ddf), TOBN(0xc8e19b0d, 0xff9eb33b)}},
+ {{TOBN(0xc8cc943f, 0xb569a5fe), TOBN(0xad0090d4, 0xd4342d75),
+ TOBN(0x82090b4b, 0xcaeca000), TOBN(0xca39687f, 0x1bd410eb)},
+ {TOBN(0xe7bb0df7, 0x65959d77), TOBN(0x39d78218, 0x9c964999),
+ TOBN(0xd87f62e8, 0xb2415451), TOBN(0xe5efb774, 0xbed76108)}},
+ {{TOBN(0x3ea011a4, 0xe822f0d0), TOBN(0xbc647ad1, 0x5a8704f8),
+ TOBN(0xbb315b35, 0x50c6820f), TOBN(0x863dec3d, 0xb7e76bec)},
+ {TOBN(0x01ff5d3a, 0xf017bfc7), TOBN(0x20054439, 0x976b8229),
+ TOBN(0x067fca37, 0x0bbd0d3b), TOBN(0xf63dde64, 0x7f5e3d0f)}},
+ {{TOBN(0x22dbefb3, 0x2a4c94e9), TOBN(0xafbff0fe, 0x96f8278a),
+ TOBN(0x80aea0b1, 0x3503793d), TOBN(0xb2238029, 0x5f06cd29)},
+ {TOBN(0x65703e57, 0x8ec3feca), TOBN(0x06c38314, 0x393e7053),
+ TOBN(0xa0b751eb, 0x7c6734c4), TOBN(0xd2e8a435, 0xc59f0f1e)}},
+ {{TOBN(0x147d9052, 0x5e9ca895), TOBN(0x2f4dd31e, 0x972072df),
+ TOBN(0xa16fda8e, 0xe6c6755c), TOBN(0xc66826ff, 0xcf196558)},
+ {TOBN(0x1f1a76a3, 0x0cf43895), TOBN(0xa9d604e0, 0x83c3097b),
+ TOBN(0xe1908309, 0x66390e0e), TOBN(0xa50bf753, 0xb3c85eff)}},
+ {{TOBN(0x0696bdde, 0xf6a70251), TOBN(0x548b801b, 0x3c6ab16a),
+ TOBN(0x37fcf704, 0xa4d08762), TOBN(0x090b3def, 0xdff76c4e)},
+ {TOBN(0x87e8cb89, 0x69cb9158), TOBN(0x44a90744, 0x995ece43),
+ TOBN(0xf85395f4, 0x0ad9fbf5), TOBN(0x49b0f6c5, 0x4fb0c82d)}},
+ {{TOBN(0x75d9bc15, 0xadf7cccf), TOBN(0x81a3e5d6, 0xdfa1e1b0),
+ TOBN(0x8c39e444, 0x249bc17e), TOBN(0xf37dccb2, 0x8ea7fd43)},
+ {TOBN(0xda654873, 0x907fba12), TOBN(0x35daa6da, 0x4a372904),
+ TOBN(0x0564cfc6, 0x6283a6c5), TOBN(0xd09fa4f6, 0x4a9395bf)}},
+ {{TOBN(0x688e9ec9, 0xaeb19a36), TOBN(0xd913f1ce, 0xc7bfbfb4),
+ TOBN(0x797b9a3c, 0x61c2faa6), TOBN(0x2f979bec, 0x6a0a9c12)},
+ {TOBN(0xb5969d0f, 0x359679ec), TOBN(0xebcf523d, 0x079b0460),
+ TOBN(0xfd6b0008, 0x10fab870), TOBN(0x3f2edcda, 0x9373a39c)}},
+ {{TOBN(0x0d64f9a7, 0x6f568431), TOBN(0xf848c27c, 0x02f8898c),
+ TOBN(0xf418ade1, 0x260b5bd5), TOBN(0xc1f3e323, 0x6973dee8)},
+ {TOBN(0x46e9319c, 0x26c185dd), TOBN(0x6d85b7d8, 0x546f0ac4),
+ TOBN(0x427965f2, 0x247f9d57), TOBN(0xb519b636, 0xb0035f48)}},
+ {{TOBN(0x6b6163a9, 0xab87d59c), TOBN(0xff9f58c3, 0x39caaa11),
+ TOBN(0x4ac39cde, 0x3177387b), TOBN(0x5f6557c2, 0x873e77f9)},
+ {TOBN(0x67504006, 0x36a83041), TOBN(0x9b1c96ca, 0x75ef196c),
+ TOBN(0xf34283de, 0xb08c7940), TOBN(0x7ea09644, 0x1128c316)}},
+ {{TOBN(0xb510b3b5, 0x6aa39dff), TOBN(0x59b43da2, 0x9f8e4d8c),
+ TOBN(0xa8ce31fd, 0x9e4c4b9f), TOBN(0x0e20be26, 0xc1303c01)},
+ {TOBN(0x18187182, 0xe8ee47c9), TOBN(0xd9687cdb, 0x7db98101),
+ TOBN(0x7a520e4d, 0xa1e14ff6), TOBN(0x429808ba, 0x8836d572)}},
+ {{TOBN(0xa37ca60d, 0x4944b663), TOBN(0xf901f7a9, 0xa3f91ae5),
+ TOBN(0xe4e3e76e, 0x9e36e3b1), TOBN(0x9aa219cf, 0x29d93250)},
+ {TOBN(0x347fe275, 0x056a2512), TOBN(0xa4d643d9, 0xde65d95c),
+ TOBN(0x9669d396, 0x699fc3ed), TOBN(0xb598dee2, 0xcf8c6bbe)}},
+ {{TOBN(0x682ac1e5, 0xdda9e5c6), TOBN(0x4e0d3c72, 0xcaa9fc95),
+ TOBN(0x17faaade, 0x772bea44), TOBN(0x5ef8428c, 0xab0009c8)},
+ {TOBN(0xcc4ce47a, 0x460ff016), TOBN(0xda6d12bf, 0x725281cb),
+ TOBN(0x44c67848, 0x0223aad2), TOBN(0x6e342afa, 0x36256e28)}},
+ {{TOBN(0x1400bb0b, 0x93a37c04), TOBN(0x62b1bc9b, 0xdd10bd96),
+ TOBN(0x7251adeb, 0x0dac46b7), TOBN(0x7d33b92e, 0x7be4ef51)},
+ {TOBN(0x28b2a94b, 0xe61fa29a), TOBN(0x4b2be13f, 0x06422233),
+ TOBN(0x36d6d062, 0x330d8d37), TOBN(0x5ef80e1e, 0xb28ca005)}},
+ {{TOBN(0x174d4699, 0x6d16768e), TOBN(0x9fc4ff6a, 0x628bf217),
+ TOBN(0x77705a94, 0x154e490d), TOBN(0x9d96dd28, 0x8d2d997a)},
+ {TOBN(0x77e2d9d8, 0xce5d72c4), TOBN(0x9d06c5a4, 0xc11c714f),
+ TOBN(0x02aa5136, 0x79e4a03e), TOBN(0x1386b3c2, 0x030ff28b)}},
+ {{TOBN(0xfe82e8a6, 0xfb283f61), TOBN(0x7df203e5, 0xf3abc3fb),
+ TOBN(0xeec7c351, 0x3a4d3622), TOBN(0xf7d17dbf, 0xdf762761)},
+ {TOBN(0xc3956e44, 0x522055f0), TOBN(0xde3012db, 0x8fa748db),
+ TOBN(0xca9fcb63, 0xbf1dcc14), TOBN(0xa56d9dcf, 0xbe4e2f3a)}},
+ {{TOBN(0xb86186b6, 0x8bcec9c2), TOBN(0x7cf24df9, 0x680b9f06),
+ TOBN(0xc46b45ea, 0xc0d29281), TOBN(0xfff42bc5, 0x07b10e12)},
+ {TOBN(0x12263c40, 0x4d289427), TOBN(0x3d5f1899, 0xb4848ec4),
+ TOBN(0x11f97010, 0xd040800c), TOBN(0xb4c5f529, 0x300feb20)}},
+ {{TOBN(0xcc543f8f, 0xde94fdcb), TOBN(0xe96af739, 0xc7c2f05e),
+ TOBN(0xaa5e0036, 0x882692e1), TOBN(0x09c75b68, 0x950d4ae9)},
+ {TOBN(0x62f63df2, 0xb5932a7a), TOBN(0x2658252e, 0xde0979ad),
+ TOBN(0x2a19343f, 0xb5e69631), TOBN(0x718c7501, 0x525b666b)}},
+ {{TOBN(0x26a42d69, 0xea40dc3a), TOBN(0xdc84ad22, 0xaecc018f),
+ TOBN(0x25c36c7b, 0x3270f04a), TOBN(0x46ba6d47, 0x50fa72ed)},
+ {TOBN(0x6c37d1c5, 0x93e58a8e), TOBN(0xa2394731, 0x120c088c),
+ TOBN(0xc3be4263, 0xcb6e86da), TOBN(0x2c417d36, 0x7126d038)}},
+ {{TOBN(0x5b70f9c5, 0x8b6f8efa), TOBN(0x671a2faa, 0x37718536),
+ TOBN(0xd3ced3c6, 0xb539c92b), TOBN(0xe56f1bd9, 0xa31203c2)},
+ {TOBN(0x8b096ec4, 0x9ff3c8eb), TOBN(0x2deae432, 0x43491cea),
+ TOBN(0x2465c6eb, 0x17943794), TOBN(0x5d267e66, 0x20586843)}},
+ {{TOBN(0x9d3d116d, 0xb07159d0), TOBN(0xae07a67f, 0xc1896210),
+ TOBN(0x8fc84d87, 0xbb961579), TOBN(0x30009e49, 0x1c1f8dd6)},
+ {TOBN(0x8a8caf22, 0xe3132819), TOBN(0xcffa197c, 0xf23ab4ff),
+ TOBN(0x58103a44, 0x205dd687), TOBN(0x57b796c3, 0x0ded67a2)}},
+ {{TOBN(0x0b9c3a6c, 0xa1779ad7), TOBN(0xa33cfe2e, 0x357c09c5),
+ TOBN(0x2ea29315, 0x3db4a57e), TOBN(0x91959695, 0x8ebeb52e)},
+ {TOBN(0x118db9a6, 0xe546c879), TOBN(0x8e996df4, 0x6295c8d6),
+ TOBN(0xdd990484, 0x55ec806b), TOBN(0x24f291ca, 0x165c1035)}},
+ {{TOBN(0xcca523bb, 0x440e2229), TOBN(0x324673a2, 0x73ef4d04),
+ TOBN(0xaf3adf34, 0x3e11ec39), TOBN(0x6136d7f1, 0xdc5968d3)},
+ {TOBN(0x7a7b2899, 0xb053a927), TOBN(0x3eaa2661, 0xae067ecd),
+ TOBN(0x8549b9c8, 0x02779cd9), TOBN(0x061d7940, 0xc53385ea)}},
+ {{TOBN(0x3e0ba883, 0xf06d18bd), TOBN(0x4ba6de53, 0xb2700843),
+ TOBN(0xb966b668, 0x591a9e4d), TOBN(0x93f67567, 0x7f4fa0ed)},
+ {TOBN(0x5a02711b, 0x4347237b), TOBN(0xbc041e2f, 0xe794608e),
+ TOBN(0x55af10f5, 0x70f73d8c), TOBN(0xd2d4d4f7, 0xbb7564f7)}},
+ {{TOBN(0xd7d27a89, 0xb3e93ce7), TOBN(0xf7b5a875, 0x5d3a2c1b),
+ TOBN(0xb29e68a0, 0x255b218a), TOBN(0xb533837e, 0x8af76754)},
+ {TOBN(0xd1b05a73, 0x579fab2e), TOBN(0xb41055a1, 0xecd74385),
+ TOBN(0xb2369274, 0x445e9115), TOBN(0x2972a7c4, 0xf520274e)}},
+ {{TOBN(0x6c08334e, 0xf678e68a), TOBN(0x4e4160f0, 0x99b057ed),
+ TOBN(0x3cfe11b8, 0x52ccb69a), TOBN(0x2fd1823a, 0x21c8f772)},
+ {TOBN(0xdf7f072f, 0x3298f055), TOBN(0x8c0566f9, 0xfec74a6e),
+ TOBN(0xe549e019, 0x5bb4d041), TOBN(0x7c3930ba, 0x9208d850)}},
+ {{TOBN(0xe07141fc, 0xaaa2902b), TOBN(0x539ad799, 0xe4f69ad3),
+ TOBN(0xa6453f94, 0x813f9ffd), TOBN(0xc58d3c48, 0x375bc2f7)},
+ {TOBN(0xb3326fad, 0x5dc64e96), TOBN(0x3aafcaa9, 0xb240e354),
+ TOBN(0x1d1b0903, 0xaca1e7a9), TOBN(0x4ceb9767, 0x1211b8a0)}},
+ {{TOBN(0xeca83e49, 0xe32a858e), TOBN(0x4c32892e, 0xae907bad),
+ TOBN(0xd5b42ab6, 0x2eb9b494), TOBN(0x7fde3ee2, 0x1eabae1b)},
+ {TOBN(0x13b5ab09, 0xcaf54957), TOBN(0xbfb028be, 0xe5f5d5d5),
+ TOBN(0x928a0650, 0x2003e2c0), TOBN(0x90793aac, 0x67476843)}},
+ {{TOBN(0x5e942e79, 0xc81710a0), TOBN(0x557e4a36, 0x27ccadd4),
+ TOBN(0x72a2bc56, 0x4bcf6d0c), TOBN(0x09ee5f43, 0x26d7b80c)},
+ {TOBN(0x6b70dbe9, 0xd4292f19), TOBN(0x56f74c26, 0x63f16b18),
+ TOBN(0xc23db0f7, 0x35fbb42a), TOBN(0xb606bdf6, 0x6ae10040)}},
+ {{TOBN(0x1eb15d4d, 0x044573ac), TOBN(0x7dc3cf86, 0x556b0ba4),
+ TOBN(0x97af9a33, 0xc60df6f7), TOBN(0x0b1ef85c, 0xa716ce8c)},
+ {TOBN(0x2922f884, 0xc96958be), TOBN(0x7c32fa94, 0x35690963),
+ TOBN(0x2d7f667c, 0xeaa00061), TOBN(0xeaaf7c17, 0x3547365c)}},
+ {{TOBN(0x1eb4de46, 0x87032d58), TOBN(0xc54f3d83, 0x5e2c79e0),
+ TOBN(0x07818df4, 0x5d04ef23), TOBN(0x55faa9c8, 0x673d41b4)},
+ {TOBN(0xced64f6f, 0x89b95355), TOBN(0x4860d2ea, 0xb7415c84),
+ TOBN(0x5fdb9bd2, 0x050ebad3), TOBN(0xdb53e0cc, 0x6685a5bf)}},
+ {{TOBN(0xb830c031, 0x9feb6593), TOBN(0xdd87f310, 0x6accff17),
+ TOBN(0x2303ebab, 0x9f555c10), TOBN(0x94603695, 0x287e7065)},
+ {TOBN(0xf88311c3, 0x2e83358c), TOBN(0x508dd9b4, 0xeefb0178),
+ TOBN(0x7ca23706, 0x2dba8652), TOBN(0x62aac5a3, 0x0047abe5)}},
+ {{TOBN(0x9a61d2a0, 0x8b1ea7b3), TOBN(0xd495ab63, 0xae8b1485),
+ TOBN(0x38740f84, 0x87052f99), TOBN(0x178ebe5b, 0xb2974eea)},
+ {TOBN(0x030bbcca, 0x5b36d17f), TOBN(0xb5e4cce3, 0xaaf86eea),
+ TOBN(0xb51a0220, 0x68f8e9e0), TOBN(0xa4348796, 0x09eb3e75)}},
+ {{TOBN(0xbe592309, 0xeef1a752), TOBN(0x5d7162d7, 0x6f2aa1ed),
+ TOBN(0xaebfb5ed, 0x0f007dd2), TOBN(0x255e14b2, 0xc89edd22)},
+ {TOBN(0xba85e072, 0x0303b697), TOBN(0xc5d17e25, 0xf05720ff),
+ TOBN(0x02b58d6e, 0x5128ebb6), TOBN(0x2c80242d, 0xd754e113)}},
+ {{TOBN(0x919fca5f, 0xabfae1ca), TOBN(0x937afaac, 0x1a21459b),
+ TOBN(0x9e0ca91c, 0x1f66a4d2), TOBN(0x194cc7f3, 0x23ec1331)},
+ {TOBN(0xad25143a, 0x8aa11690), TOBN(0xbe40ad8d, 0x09b59e08),
+ TOBN(0x37d60d9b, 0xe750860a), TOBN(0x6c53b008, 0xc6bf434c)}},
+ {{TOBN(0xb572415d, 0x1356eb80), TOBN(0xb8bf9da3, 0x9578ded8),
+ TOBN(0x22658e36, 0x5e8fb38b), TOBN(0x9b70ce22, 0x5af8cb22)},
+ {TOBN(0x7c00018a, 0x829a8180), TOBN(0x84329f93, 0xb81ed295),
+ TOBN(0x7c343ea2, 0x5f3cea83), TOBN(0x38f8655f, 0x67586536)}},
+ {{TOBN(0xa661a0d0, 0x1d3ec517), TOBN(0x98744652, 0x512321ae),
+ TOBN(0x084ca591, 0xeca92598), TOBN(0xa9bb9dc9, 0x1dcb3feb)},
+ {TOBN(0x14c54355, 0x78b4c240), TOBN(0x5ed62a3b, 0x610cafdc),
+ TOBN(0x07512f37, 0x1b38846b), TOBN(0x571bb70a, 0xb0e38161)}},
+ {{TOBN(0xb556b95b, 0x2da705d2), TOBN(0x3ef8ada6, 0xb1a08f98),
+ TOBN(0x85302ca7, 0xddecfbe5), TOBN(0x0e530573, 0x943105cd)},
+ {TOBN(0x60554d55, 0x21a9255d), TOBN(0x63a32fa1, 0xf2f3802a),
+ TOBN(0x35c8c5b0, 0xcd477875), TOBN(0x97f458ea, 0x6ad42da1)}},
+ {{TOBN(0x832d7080, 0xeb6b242d), TOBN(0xd30bd023, 0x3b71e246),
+ TOBN(0x7027991b, 0xbe31139d), TOBN(0x68797e91, 0x462e4e53)},
+ {TOBN(0x423fe20a, 0x6b4e185a), TOBN(0x82f2c67e, 0x42d9b707),
+ TOBN(0x25c81768, 0x4cf7811b), TOBN(0xbd53005e, 0x045bb95d)}}},
+ {{{TOBN(0xe5f649be, 0x9d8e68fd), TOBN(0xdb0f0533, 0x1b044320),
+ TOBN(0xf6fde9b3, 0xe0c33398), TOBN(0x92f4209b, 0x66c8cfae)},
+ {TOBN(0xe9d1afcc, 0x1a739d4b), TOBN(0x09aea75f, 0xa28ab8de),
+ TOBN(0x14375fb5, 0xeac6f1d0), TOBN(0x6420b560, 0x708f7aa5)}},
+ {{TOBN(0x9eae499c, 0x6254dc41), TOBN(0x7e293924, 0x7a837e7e),
+ TOBN(0x74aec08c, 0x090524a7), TOBN(0xf82b9219, 0x8d6f55f2)},
+ {TOBN(0x493c962e, 0x1402cec5), TOBN(0x9f17ca17, 0xfa2f30e7),
+ TOBN(0xbcd783e8, 0xe9b879cb), TOBN(0xea3d8c14, 0x5a6f145f)}},
+ {{TOBN(0xdede15e7, 0x5e0dee6e), TOBN(0x74f24872, 0xdc628aa2),
+ TOBN(0xd3e9c4fe, 0x7861bb93), TOBN(0x56d4822a, 0x6187b2e0)},
+ {TOBN(0xb66417cf, 0xc59826f9), TOBN(0xca260969, 0x2408169e),
+ TOBN(0xedf69d06, 0xc79ef885), TOBN(0x00031f8a, 0xdc7d138f)}},
+ {{TOBN(0x103c46e6, 0x0ebcf726), TOBN(0x4482b831, 0x6231470e),
+ TOBN(0x6f6dfaca, 0x487c2109), TOBN(0x2e0ace97, 0x62e666ef)},
+ {TOBN(0x3246a9d3, 0x1f8d1f42), TOBN(0x1b1e83f1, 0x574944d2),
+ TOBN(0x13dfa63a, 0xa57f334b), TOBN(0x0cf8daed, 0x9f025d81)}},
+ {{TOBN(0x30d78ea8, 0x00ee11c1), TOBN(0xeb053cd4, 0xb5e3dd75),
+ TOBN(0x9b65b13e, 0xd58c43c5), TOBN(0xc3ad49bd, 0xbd151663)},
+ {TOBN(0x99fd8e41, 0xb6427990), TOBN(0x12cf15bd, 0x707eae1e),
+ TOBN(0x29ad4f1b, 0x1aabb71e), TOBN(0x5143e74d, 0x07545d0e)}},
+ {{TOBN(0x30266336, 0xc88bdee1), TOBN(0x25f29306, 0x5876767c),
+ TOBN(0x9c078571, 0xc6731996), TOBN(0xc88690b2, 0xed552951)},
+ {TOBN(0x274f2c2d, 0x852705b4), TOBN(0xb0bf8d44, 0x4e09552d),
+ TOBN(0x7628beeb, 0x986575d1), TOBN(0x407be238, 0x7f864651)}},
+ {{TOBN(0x0e5e3049, 0xa639fc6b), TOBN(0xe75c35d9, 0x86003625),
+ TOBN(0x0cf35bd8, 0x5dcc1646), TOBN(0x8bcaced2, 0x6c26273a)},
+ {TOBN(0xe22ecf1d, 0xb5536742), TOBN(0x013dd897, 0x1a9e068b),
+ TOBN(0x17f411cb, 0x8a7909c5), TOBN(0x5757ac98, 0x861dd506)}},
+ {{TOBN(0x85de1f0d, 0x1e935abb), TOBN(0xdefd10b4, 0x154de37a),
+ TOBN(0xb8d9e392, 0x369cebb5), TOBN(0x54d5ef9b, 0x761324be)},
+ {TOBN(0x4d6341ba, 0x74f17e26), TOBN(0xc0a0e3c8, 0x78c1dde4),
+ TOBN(0xa6d77581, 0x87d918fd), TOBN(0x66876015, 0x02ca3a13)}},
+ {{TOBN(0xc7313e9c, 0xf36658f0), TOBN(0xc433ef1c, 0x71f8057e),
+ TOBN(0x85326246, 0x1b6a835a), TOBN(0xc8f05398, 0x7c86394c)},
+ {TOBN(0xff398cdf, 0xe983c4a1), TOBN(0xbf5e8162, 0x03b7b931),
+ TOBN(0x93193c46, 0xb7b9045b), TOBN(0x1e4ebf5d, 0xa4a6e46b)}},
+ {{TOBN(0xf9942a60, 0x43a24fe7), TOBN(0x29c1191e, 0xffb3492b),
+ TOBN(0x9f662449, 0x902fde05), TOBN(0xc792a7ac, 0x6713c32d)},
+ {TOBN(0x2fd88ad8, 0xb737982c), TOBN(0x7e3a0319, 0xa21e60e3),
+ TOBN(0x09b0de44, 0x7383591a), TOBN(0x6df141ee, 0x8310a456)}},
+ {{TOBN(0xaec1a039, 0xe6d6f471), TOBN(0x14b2ba0f, 0x1198d12e),
+ TOBN(0xebc1a160, 0x3aeee5ac), TOBN(0x401f4836, 0xe0b964ce)},
+ {TOBN(0x2ee43796, 0x4fd03f66), TOBN(0x3fdb4e49, 0xdd8f3f12),
+ TOBN(0x6ef267f6, 0x29380f18), TOBN(0x3e8e9670, 0x8da64d16)}},
+ {{TOBN(0xbc19180c, 0x207674f1), TOBN(0x112e09a7, 0x33ae8fdb),
+ TOBN(0x99667554, 0x6aaeb71e), TOBN(0x79432af1, 0xe101b1c7)},
+ {TOBN(0xd5eb558f, 0xde2ddec6), TOBN(0x81392d1f, 0x5357753f),
+ TOBN(0xa7a76b97, 0x3ae1158a), TOBN(0x416fbbff, 0x4a899991)}},
+ {{TOBN(0x9e65fdfd, 0x0d4a9dcf), TOBN(0x7bc29e48, 0x944ddf12),
+ TOBN(0xbc1a92d9, 0x3c856866), TOBN(0x273c6905, 0x6e98dfe2)},
+ {TOBN(0x69fce418, 0xcdfaa6b8), TOBN(0x606bd823, 0x5061c69f),
+ TOBN(0x42d495a0, 0x6af75e27), TOBN(0x8ed3d505, 0x6d873a1f)}},
+ {{TOBN(0xaf552841, 0x6ab25b6a), TOBN(0xc6c0ffc7, 0x2b1a4523),
+ TOBN(0xab18827b, 0x21c99e03), TOBN(0x060e8648, 0x9034691b)},
+ {TOBN(0x5207f90f, 0x93c7f398), TOBN(0x9f4a96cb, 0x82f8d10b),
+ TOBN(0xdd71cd79, 0x3ad0f9e3), TOBN(0x84f435d2, 0xfc3a54f5)}},
+ {{TOBN(0x4b03c55b, 0x8e33787f), TOBN(0xef42f975, 0xa6384673),
+ TOBN(0xff7304f7, 0x5051b9f0), TOBN(0x18aca1dc, 0x741c87c2)},
+ {TOBN(0x56f120a7, 0x2d4bfe80), TOBN(0xfd823b3d, 0x053e732c),
+ TOBN(0x11bccfe4, 0x7537ca16), TOBN(0xdf6c9c74, 0x1b5a996b)}},
+ {{TOBN(0xee7332c7, 0x904fc3fa), TOBN(0x14a23f45, 0xc7e3636a),
+ TOBN(0xc38659c3, 0xf091d9aa), TOBN(0x4a995e5d, 0xb12d8540)},
+ {TOBN(0x20a53bec, 0xf3a5598a), TOBN(0x56534b17, 0xb1eaa995),
+ TOBN(0x9ed3dca4, 0xbf04e03c), TOBN(0x716c563a, 0xd8d56268)}},
+ {{TOBN(0x27ba77a4, 0x1d6178e7), TOBN(0xe4c80c40, 0x68a1ff8e),
+ TOBN(0x75011099, 0x0a13f63d), TOBN(0x7bf33521, 0xa61d46f3)},
+ {TOBN(0x0aff218e, 0x10b365bb), TOBN(0x81021804, 0x0fd7ea75),
+ TOBN(0x05a3fd8a, 0xa4b3a925), TOBN(0xb829e75f, 0x9b3db4e6)}},
+ {{TOBN(0x6bdc75a5, 0x4d53e5fb), TOBN(0x04a5dc02, 0xd52717e3),
+ TOBN(0x86af502f, 0xe9a42ec2), TOBN(0x8867e8fb, 0x2630e382)},
+ {TOBN(0xbf845c6e, 0xbec9889b), TOBN(0x54f491f2, 0xcb47c98d),
+ TOBN(0xa3091fba, 0x790c2a12), TOBN(0xd7f6fd78, 0xc20f708b)}},
+ {{TOBN(0xa569ac30, 0xacde5e17), TOBN(0xd0f996d0, 0x6852b4d7),
+ TOBN(0xe51d4bb5, 0x4609ae54), TOBN(0x3fa37d17, 0x0daed061)},
+ {TOBN(0x62a88684, 0x34b8fb41), TOBN(0x99a2acbd, 0x9efb64f1),
+ TOBN(0xb75c1a5e, 0x6448e1f2), TOBN(0xfa99951a, 0x42b5a069)}},
+ {{TOBN(0x6d956e89, 0x2f3b26e7), TOBN(0xf4709860, 0xda875247),
+ TOBN(0x3ad15179, 0x2482dda3), TOBN(0xd64110e3, 0x017d82f0)},
+ {TOBN(0x14928d2c, 0xfad414e4), TOBN(0x2b155f58, 0x2ed02b24),
+ TOBN(0x481a141b, 0xcb821bf1), TOBN(0x12e3c770, 0x4f81f5da)}},
+ {{TOBN(0xe49c5de5, 0x9fff8381), TOBN(0x11053232, 0x5bbec894),
+ TOBN(0xa0d051cc, 0x454d88c4), TOBN(0x4f6db89c, 0x1f8e531b)},
+ {TOBN(0x34fe3fd6, 0xca563a44), TOBN(0x7f5c2215, 0x58da8ab9),
+ TOBN(0x8445016d, 0x9474f0a1), TOBN(0x17d34d61, 0xcb7d8a0a)}},
+ {{TOBN(0x8e9d3910, 0x1c474019), TOBN(0xcaff2629, 0xd52ceefb),
+ TOBN(0xf9cf3e32, 0xc1622c2b), TOBN(0xd4b95e3c, 0xe9071a05)},
+ {TOBN(0xfbbca61f, 0x1594438c), TOBN(0x1eb6e6a6, 0x04aadedf),
+ TOBN(0x853027f4, 0x68e14940), TOBN(0x221d322a, 0xdfabda9c)}},
+ {{TOBN(0xed8ea9f6, 0xb7cb179a), TOBN(0xdc7b764d, 0xb7934dcc),
+ TOBN(0xfcb13940, 0x5e09180d), TOBN(0x6629a6bf, 0xb47dc2dd)},
+ {TOBN(0xbfc55e4e, 0x9f5a915e), TOBN(0xb1db9d37, 0x6204441e),
+ TOBN(0xf82d68cf, 0x930c5f53), TOBN(0x17d3a142, 0xcbb605b1)}},
+ {{TOBN(0xdd5944ea, 0x308780f2), TOBN(0xdc8de761, 0x3845f5e4),
+ TOBN(0x6beaba7d, 0x7624d7a3), TOBN(0x1e709afd, 0x304df11e)},
+ {TOBN(0x95364376, 0x02170456), TOBN(0xbf204b3a, 0xc8f94b64),
+ TOBN(0x4e53af7c, 0x5680ca68), TOBN(0x0526074a, 0xe0c67574)}},
+ {{TOBN(0x95d8cef8, 0xecd92af6), TOBN(0xe6b9fa7a, 0x6cd1745a),
+ TOBN(0x3d546d3d, 0xa325c3e4), TOBN(0x1f57691d, 0x9ae93aae)},
+ {TOBN(0xe891f3fe, 0x9d2e1a33), TOBN(0xd430093f, 0xac063d35),
+ TOBN(0xeda59b12, 0x5513a327), TOBN(0xdc2134f3, 0x5536f18f)}},
+ {{TOBN(0xaa51fe2c, 0x5c210286), TOBN(0x3f68aaee, 0x1cab658c),
+ TOBN(0x5a23a00b, 0xf9357292), TOBN(0x9a626f39, 0x7efdabed)},
+ {TOBN(0xfe2b3bf3, 0x199d78e3), TOBN(0xb7a2af77, 0x71bbc345),
+ TOBN(0x3d19827a, 0x1e59802c), TOBN(0x823bbc15, 0xb487a51c)}},
+ {{TOBN(0x856139f2, 0x99d0a422), TOBN(0x9ac3df65, 0xf456c6fb),
+ TOBN(0xaddf65c6, 0x701f8bd6), TOBN(0x149f321e, 0x3758df87)},
+ {TOBN(0xb1ecf714, 0x721b7eba), TOBN(0xe17df098, 0x31a3312a),
+ TOBN(0xdb2fd6ec, 0xd5c4d581), TOBN(0xfd02996f, 0x8fcea1b3)}},
+ {{TOBN(0xe29fa63e, 0x7882f14f), TOBN(0xc9f6dc35, 0x07c6cadc),
+ TOBN(0x46f22d6f, 0xb882bed0), TOBN(0x1a45755b, 0xd118e52c)},
+ {TOBN(0x9f2c7c27, 0x7c4608cf), TOBN(0x7ccbdf32, 0x568012c2),
+ TOBN(0xfcb0aedd, 0x61729b0e), TOBN(0x7ca2ca9e, 0xf7d75dbf)}},
+ {{TOBN(0xf58fecb1, 0x6f640f62), TOBN(0xe274b92b, 0x39f51946),
+ TOBN(0x7f4dfc04, 0x6288af44), TOBN(0x0a91f32a, 0xeac329e5)},
+ {TOBN(0x43ad274b, 0xd6aaba31), TOBN(0x719a1640, 0x0f6884f9),
+ TOBN(0x685d29f6, 0xdaf91e20), TOBN(0x5ec1cc33, 0x27e49d52)}},
+ {{TOBN(0x38f4de96, 0x3b54a059), TOBN(0x0e0015e5, 0xefbcfdb3),
+ TOBN(0x177d23d9, 0x4dbb8da6), TOBN(0x98724aa2, 0x97a617ad)},
+ {TOBN(0x30f0885b, 0xfdb6558e), TOBN(0xf9f7a28a, 0xc7899a96),
+ TOBN(0xd2ae8ac8, 0x872dc112), TOBN(0xfa0642ca, 0x73c3c459)}},
+ {{TOBN(0x15296981, 0xe7dfc8d6), TOBN(0x67cd4450, 0x1fb5b94a),
+ TOBN(0x0ec71cf1, 0x0eddfd37), TOBN(0xc7e5eeb3, 0x9a8eddc7)},
+ {TOBN(0x02ac8e3d, 0x81d95028), TOBN(0x0088f172, 0x70b0e35d),
+ TOBN(0xec041fab, 0xe1881fe3), TOBN(0x62cf71b8, 0xd99e7faa)}},
+ {{TOBN(0x5043dea7, 0xe0f222c2), TOBN(0x309d42ac, 0x72e65142),
+ TOBN(0x94fe9ddd, 0x9216cd30), TOBN(0xd6539c7d, 0x0f87feec)},
+ {TOBN(0x03c5a57c, 0x432ac7d7), TOBN(0x72692cf0, 0x327fda10),
+ TOBN(0xec28c85f, 0x280698de), TOBN(0x2331fb46, 0x7ec283b1)}},
+ {{TOBN(0xd34bfa32, 0x2867e633), TOBN(0x78709a82, 0x0a9cc815),
+ TOBN(0xb7fe6964, 0x875e2fa5), TOBN(0x25cc064f, 0x9e98bfb5)},
+ {TOBN(0x9eb0151c, 0x493a65c5), TOBN(0x5fb5d941, 0x53182464),
+ TOBN(0x69e6f130, 0xf04618e2), TOBN(0xa8ecec22, 0xf89c8ab6)}},
+ {{TOBN(0xcd6ac88b, 0xb96209bd), TOBN(0x65fa8cdb, 0xb3e1c9e0),
+ TOBN(0xa47d22f5, 0x4a8d8eac), TOBN(0x83895cdf, 0x8d33f963)},
+ {TOBN(0xa8adca59, 0xb56cd3d1), TOBN(0x10c8350b, 0xdaf38232),
+ TOBN(0x2b161fb3, 0xa5080a9f), TOBN(0xbe7f5c64, 0x3af65b3a)}},
+ {{TOBN(0x2c754039, 0x97403a11), TOBN(0x94626cf7, 0x121b96af),
+ TOBN(0x431de7c4, 0x6a983ec2), TOBN(0x3780dd3a, 0x52cc3df7)},
+ {TOBN(0xe28a0e46, 0x2baf8e3b), TOBN(0xabe68aad, 0x51d299ae),
+ TOBN(0x603eb8f9, 0x647a2408), TOBN(0x14c61ed6, 0x5c750981)}},
+ {{TOBN(0x88b34414, 0xc53352e7), TOBN(0x5a34889c, 0x1337d46e),
+ TOBN(0x612c1560, 0xf95f2bc8), TOBN(0x8a3f8441, 0xd4807a3a)},
+ {TOBN(0x680d9e97, 0x5224da68), TOBN(0x60cd6e88, 0xc3eb00e9),
+ TOBN(0x3875a98e, 0x9a6bc375), TOBN(0xdc80f924, 0x4fd554c2)}},
+ {{TOBN(0x6c4b3415, 0x6ac77407), TOBN(0xa1e5ea8f, 0x25420681),
+ TOBN(0x541bfa14, 0x4607a458), TOBN(0x5dbc7e7a, 0x96d7fbf9)},
+ {TOBN(0x646a851b, 0x31590a47), TOBN(0x039e85ba, 0x15ee6df8),
+ TOBN(0xd19fa231, 0xd7b43fc0), TOBN(0x84bc8be8, 0x299a0e04)}},
+ {{TOBN(0x2b9d2936, 0xf20df03a), TOBN(0x24054382, 0x8608d472),
+ TOBN(0x76b6ba04, 0x9149202a), TOBN(0xb21c3831, 0x3670e7b7)},
+ {TOBN(0xddd93059, 0xd6fdee10), TOBN(0x9da47ad3, 0x78488e71),
+ TOBN(0x99cc1dfd, 0xa0fcfb25), TOBN(0x42abde10, 0x64696954)}},
+ {{TOBN(0x14cc15fc, 0x17eab9fe), TOBN(0xd6e863e4, 0xd3e70972),
+ TOBN(0x29a7765c, 0x6432112c), TOBN(0x88660001, 0x5b0774d8)},
+ {TOBN(0x3729175a, 0x2c088eae), TOBN(0x13afbcae, 0x8230b8d4),
+ TOBN(0x44768151, 0x915f4379), TOBN(0xf086431a, 0xd8d22812)}},
+ {{TOBN(0x37461955, 0xc298b974), TOBN(0x905fb5f0, 0xf8711e04),
+ TOBN(0x787abf3a, 0xfe969d18), TOBN(0x392167c2, 0x6f6a494e)},
+ {TOBN(0xfc7a0d2d, 0x28c511da), TOBN(0xf127c7dc, 0xb66a262d),
+ TOBN(0xf9c4bb95, 0xfd63fdf0), TOBN(0x90016589, 0x3913ef46)}},
+ {{TOBN(0x74d2a73c, 0x11aa600d), TOBN(0x2f5379bd, 0x9fb5ab52),
+ TOBN(0xe49e53a4, 0x7fb70068), TOBN(0x68dd39e5, 0x404aa9a7)},
+ {TOBN(0xb9b0cf57, 0x2ecaa9c3), TOBN(0xba0e103b, 0xe824826b),
+ TOBN(0x60c2198b, 0x4631a3c4), TOBN(0xc5ff84ab, 0xfa8966a2)}},
+ {{TOBN(0x2d6ebe22, 0xac95aff8), TOBN(0x1c9bb6db, 0xb5a46d09),
+ TOBN(0x419062da, 0x53ee4f8d), TOBN(0x7b9042d0, 0xbb97efef)},
+ {TOBN(0x0f87f080, 0x830cf6bd), TOBN(0x4861d19a, 0x6ec8a6c6),
+ TOBN(0xd3a0daa1, 0x202f01aa), TOBN(0xb0111674, 0xf25afbd5)}},
+ {{TOBN(0x6d00d6cf, 0x1afb20d9), TOBN(0x13695000, 0x40671bc5),
+ TOBN(0x913ab0dc, 0x2485ea9b), TOBN(0x1f2bed06, 0x9eef61ac)},
+ {TOBN(0x850c8217, 0x6d799e20), TOBN(0x93415f37, 0x3271c2de),
+ TOBN(0x5afb06e9, 0x6c4f5910), TOBN(0x688a52df, 0xc4e9e421)}},
+ {{TOBN(0x30495ba3, 0xe2a9a6db), TOBN(0x4601303d, 0x58f9268b),
+ TOBN(0xbe3b0dad, 0x7eb0f04f), TOBN(0x4ea47250, 0x4456936d)},
+ {TOBN(0x8caf8798, 0xd33fd3e7), TOBN(0x1ccd8a89, 0xeb433708),
+ TOBN(0x9effe3e8, 0x87fd50ad), TOBN(0xbe240a56, 0x6b29c4df)}},
+ {{TOBN(0xec4ffd98, 0xca0e7ebd), TOBN(0xf586783a, 0xe748616e),
+ TOBN(0xa5b00d8f, 0xc77baa99), TOBN(0x0acada29, 0xb4f34c9c)},
+ {TOBN(0x36dad67d, 0x0fe723ac), TOBN(0x1d8e53a5, 0x39c36c1e),
+ TOBN(0xe4dd342d, 0x1f4bea41), TOBN(0x64fd5e35, 0xebc9e4e0)}},
+ {{TOBN(0x96f01f90, 0x57908805), TOBN(0xb5b9ea3d, 0x5ed480dd),
+ TOBN(0x366c5dc2, 0x3efd2dd0), TOBN(0xed2fe305, 0x6e9dfa27)},
+ {TOBN(0x4575e892, 0x6e9197e2), TOBN(0x11719c09, 0xab502a5d),
+ TOBN(0x264c7bec, 0xe81f213f), TOBN(0x741b9241, 0x55f5c457)}},
+ {{TOBN(0x78ac7b68, 0x49a5f4f4), TOBN(0xf91d70a2, 0x9fc45b7d),
+ TOBN(0x39b05544, 0xb0f5f355), TOBN(0x11f06bce, 0xeef930d9)},
+ {TOBN(0xdb84d25d, 0x038d05e1), TOBN(0x04838ee5, 0xbacc1d51),
+ TOBN(0x9da3ce86, 0x9e8ee00b), TOBN(0xc3412057, 0xc36eda1f)}},
+ {{TOBN(0xae80b913, 0x64d9c2f4), TOBN(0x7468bac3, 0xa010a8ff),
+ TOBN(0xdfd20037, 0x37359d41), TOBN(0x1a0f5ab8, 0x15efeacc)},
+ {TOBN(0x7c25ad2f, 0x659d0ce0), TOBN(0x4011bcbb, 0x6785cff1),
+ TOBN(0x128b9912, 0x7e2192c7), TOBN(0xa549d8e1, 0x13ccb0e8)}},
+ {{TOBN(0x805588d8, 0xc85438b1), TOBN(0x5680332d, 0xbc25cb27),
+ TOBN(0xdcd1bc96, 0x1a4bfdf4), TOBN(0x779ff428, 0x706f6566)},
+ {TOBN(0x8bbee998, 0xf059987a), TOBN(0xf6ce8cf2, 0xcc686de7),
+ TOBN(0xf8ad3c4a, 0x953cfdb2), TOBN(0xd1d426d9, 0x2205da36)}},
+ {{TOBN(0xb3c0f13f, 0xc781a241), TOBN(0x3e89360e, 0xd75362a8),
+ TOBN(0xccd05863, 0xc8a91184), TOBN(0x9bd0c9b7, 0xefa8a7f4)},
+ {TOBN(0x97ee4d53, 0x8a912a4b), TOBN(0xde5e15f8, 0xbcf518fd),
+ TOBN(0x6a055bf8, 0xc467e1e0), TOBN(0x10be4b4b, 0x1587e256)}},
+ {{TOBN(0xd90c14f2, 0x668621c9), TOBN(0xd5518f51, 0xab9c92c1),
+ TOBN(0x8e6a0100, 0xd6d47b3c), TOBN(0xcbe980dd, 0x66716175)},
+ {TOBN(0x500d3f10, 0xddd83683), TOBN(0x3b6cb35d, 0x99cac73c),
+ TOBN(0x53730c8b, 0x6083d550), TOBN(0xcf159767, 0xdf0a1987)}},
+ {{TOBN(0x84bfcf53, 0x43ad73b3), TOBN(0x1b528c20, 0x4f035a94),
+ TOBN(0x4294edf7, 0x33eeac69), TOBN(0xb6283e83, 0x817f3240)},
+ {TOBN(0xc3fdc959, 0x0a5f25b1), TOBN(0xefaf8aa5, 0x5844ee22),
+ TOBN(0xde269ba5, 0xdbdde4de), TOBN(0xe3347160, 0xc56133bf)}},
+ {{TOBN(0xc1184219, 0x8d9ea9f8), TOBN(0x090de5db, 0xf3fc1ab5),
+ TOBN(0x404c37b1, 0x0bf22cda), TOBN(0x7de20ec8, 0xf5618894)},
+ {TOBN(0x754c588e, 0xecdaecab), TOBN(0x6ca4b0ed, 0x88342743),
+ TOBN(0x76f08bdd, 0xf4a938ec), TOBN(0xd182de89, 0x91493ccb)}},
+ {{TOBN(0xd652c53e, 0xc8a4186a), TOBN(0xb3e878db, 0x946d8e33),
+ TOBN(0x088453c0, 0x5f37663c), TOBN(0x5cd9daaa, 0xb407748b)},
+ {TOBN(0xa1f5197f, 0x586d5e72), TOBN(0x47500be8, 0xc443ca59),
+ TOBN(0x78ef35b2, 0xe2652424), TOBN(0x09c5d26f, 0x6dd7767d)}},
+ {{TOBN(0x7175a79a, 0xa74d3f7b), TOBN(0x0428fd8d, 0xcf5ea459),
+ TOBN(0x511cb97c, 0xa5d1746d), TOBN(0x36363939, 0xe71d1278)},
+ {TOBN(0xcf2df955, 0x10350bf4), TOBN(0xb3817439, 0x60aae782),
+ TOBN(0xa748c0e4, 0x3e688809), TOBN(0x98021fbf, 0xd7a5a006)}},
+ {{TOBN(0x9076a70c, 0x0e367a98), TOBN(0xbea1bc15, 0x0f62b7c2),
+ TOBN(0x2645a68c, 0x30fe0343), TOBN(0xacaffa78, 0x699dc14f)},
+ {TOBN(0xf4469964, 0x457bf9c4), TOBN(0x0db6407b, 0x0d2ead83),
+ TOBN(0x68d56cad, 0xb2c6f3eb), TOBN(0x3b512e73, 0xf376356c)}},
+ {{TOBN(0xe43b0e1f, 0xfce10408), TOBN(0x89ddc003, 0x5a5e257d),
+ TOBN(0xb0ae0d12, 0x0362e5b3), TOBN(0x07f983c7, 0xb0519161)},
+ {TOBN(0xc2e94d15, 0x5d5231e7), TOBN(0xcff22aed, 0x0b4f9513),
+ TOBN(0xb02588dd, 0x6ad0b0b5), TOBN(0xb967d1ac, 0x11d0dcd5)}},
+ {{TOBN(0x8dac6bc6, 0xcf777b6c), TOBN(0x0062bdbd, 0x4c6d1959),
+ TOBN(0x53da71b5, 0x0ef5cc85), TOBN(0x07012c7d, 0x4006f14f)},
+ {TOBN(0x4617f962, 0xac47800d), TOBN(0x53365f2b, 0xc102ed75),
+ TOBN(0xb422efcb, 0x4ab8c9d3), TOBN(0x195cb26b, 0x34af31c9)}},
+ {{TOBN(0x3a926e29, 0x05f2c4ce), TOBN(0xbd2bdecb, 0x9856966c),
+ TOBN(0x5d16ab3a, 0x85527015), TOBN(0x9f81609e, 0x4486c231)},
+ {TOBN(0xd8b96b2c, 0xda350002), TOBN(0xbd054690, 0xfa1b7d36),
+ TOBN(0xdc90ebf5, 0xe71d79bc), TOBN(0xf241b6f9, 0x08964e4e)}},
+ {{TOBN(0x7c838643, 0x2fe3cd4c), TOBN(0xe0f33acb, 0xb4bc633c),
+ TOBN(0xb4a9ecec, 0x3d139f1f), TOBN(0x05ce69cd, 0xdc4a1f49)},
+ {TOBN(0xa19d1b16, 0xf5f98aaf), TOBN(0x45bb71d6, 0x6f23e0ef),
+ TOBN(0x33789fcd, 0x46cdfdd3), TOBN(0x9b8e2978, 0xcee040ca)}},
+ {{TOBN(0x9c69b246, 0xae0a6828), TOBN(0xba533d24, 0x7078d5aa),
+ TOBN(0x7a2e42c0, 0x7bb4fbdb), TOBN(0xcfb4879a, 0x7035385c)},
+ {TOBN(0x8c3dd30b, 0x3281705b), TOBN(0x7e361c6c, 0x404fe081),
+ TOBN(0x7b21649c, 0x3f604edf), TOBN(0x5dbf6a3f, 0xe52ffe47)}},
+ {{TOBN(0xc41b7c23, 0x4b54d9bf), TOBN(0x1374e681, 0x3511c3d9),
+ TOBN(0x1863bf16, 0xc1b2b758), TOBN(0x90e78507, 0x1e9e6a96)},
+ {TOBN(0xab4bf98d, 0x5d86f174), TOBN(0xd74e0bd3, 0x85e96fe4),
+ TOBN(0x8afde39f, 0xcac5d344), TOBN(0x90946dbc, 0xbd91b847)}},
+ {{TOBN(0xf5b42358, 0xfe1a838c), TOBN(0x05aae6c5, 0x620ac9d8),
+ TOBN(0x8e193bd8, 0xa1ce5a0b), TOBN(0x8f710571, 0x4dabfd72)},
+ {TOBN(0x8d8fdd48, 0x182caaac), TOBN(0x8c4aeefa, 0x040745cf),
+ TOBN(0x73c6c30a, 0xf3b93e6d), TOBN(0x991241f3, 0x16f42011)}},
+ {{TOBN(0xa0158eea, 0xe457a477), TOBN(0xd19857db, 0xee6ddc05),
+ TOBN(0xb3265224, 0x18c41671), TOBN(0x3ffdfc7e, 0x3c2c0d58)},
+ {TOBN(0x3a3a5254, 0x26ee7cda), TOBN(0x341b0869, 0xdf02c3a8),
+ TOBN(0xa023bf42, 0x723bbfc8), TOBN(0x3d15002a, 0x14452691)}}},
+ {{{TOBN(0x5ef7324c, 0x85edfa30), TOBN(0x25976554, 0x87d4f3da),
+ TOBN(0x352f5bc0, 0xdcb50c86), TOBN(0x8f6927b0, 0x4832a96c)},
+ {TOBN(0xd08ee1ba, 0x55f2f94c), TOBN(0x6a996f99, 0x344b45fa),
+ TOBN(0xe133cb8d, 0xa8aa455d), TOBN(0x5d0721ec, 0x758dc1f7)}},
+ {{TOBN(0x6ba7a920, 0x79e5fb67), TOBN(0xe1331feb, 0x70aa725e),
+ TOBN(0x5080ccf5, 0x7df5d837), TOBN(0xe4cae01d, 0x7ff72e21)},
+ {TOBN(0xd9243ee6, 0x0412a77d), TOBN(0x06ff7cac, 0xdf449025),
+ TOBN(0xbe75f7cd, 0x23ef5a31), TOBN(0xbc957822, 0x0ddef7a8)}},
+ {{TOBN(0x8cf7230c, 0xb0ce1c55), TOBN(0x5b534d05, 0x0bbfb607),
+ TOBN(0xee1ef113, 0x0e16363b), TOBN(0x27e0aa7a, 0xb4999e82)},
+ {TOBN(0xce1dac2d, 0x79362c41), TOBN(0x67920c90, 0x91bb6cb0),
+ TOBN(0x1e648d63, 0x2223df24), TOBN(0x0f7d9eef, 0xe32e8f28)}},
+ {{TOBN(0x6943f39a, 0xfa833834), TOBN(0x22951722, 0xa6328562),
+ TOBN(0x81d63dd5, 0x4170fc10), TOBN(0x9f5fa58f, 0xaecc2e6d)},
+ {TOBN(0xb66c8725, 0xe77d9a3b), TOBN(0x11235cea, 0x6384ebe0),
+ TOBN(0x06a8c118, 0x5845e24a), TOBN(0x0137b286, 0xebd093b1)}},
+ {{TOBN(0xc589e1ce, 0x44ace150), TOBN(0xe0f8d3d9, 0x4381e97c),
+ TOBN(0x59e99b11, 0x62c5a4b8), TOBN(0x90d262f7, 0xfd0ec9f9)},
+ {TOBN(0xfbc854c9, 0x283e13c9), TOBN(0x2d04fde7, 0xaedc7085),
+ TOBN(0x057d7765, 0x47dcbecb), TOBN(0x8dbdf591, 0x9a76fa5f)}},
+ {{TOBN(0xd0150695, 0x0de1e578), TOBN(0x2e1463e7, 0xe9f72bc6),
+ TOBN(0xffa68441, 0x1b39eca5), TOBN(0x673c8530, 0x7c037f2f)},
+ {TOBN(0xd0d6a600, 0x747f91da), TOBN(0xb08d43e1, 0xc9cb78e9),
+ TOBN(0x0fc0c644, 0x27b5cef5), TOBN(0x5c1d160a, 0xa60a2fd6)}},
+ {{TOBN(0xf98cae53, 0x28c8e13b), TOBN(0x375f10c4, 0xb2eddcd1),
+ TOBN(0xd4eb8b7f, 0x5cce06ad), TOBN(0xb4669f45, 0x80a2e1ef)},
+ {TOBN(0xd593f9d0, 0x5bbd8699), TOBN(0x5528a4c9, 0xe7976d13),
+ TOBN(0x3923e095, 0x1c7e28d3), TOBN(0xb9293790, 0x3f6bb577)}},
+ {{TOBN(0xdb567d6a, 0xc42bd6d2), TOBN(0x6df86468, 0xbb1f96ae),
+ TOBN(0x0efe5b1a, 0x4843b28e), TOBN(0x961bbb05, 0x6379b240)},
+ {TOBN(0xb6caf5f0, 0x70a6a26b), TOBN(0x70686c0d, 0x328e6e39),
+ TOBN(0x80da06cf, 0x895fc8d3), TOBN(0x804d8810, 0xb363fdc9)}},
+ {{TOBN(0xbe22877b, 0x207f1670), TOBN(0x9b0dd188, 0x4e615291),
+ TOBN(0x625ae8dc, 0x97a3c2bf), TOBN(0x08584ef7, 0x439b86e8)},
+ {TOBN(0xde7190a5, 0xdcd898ff), TOBN(0x26286c40, 0x2058ee3d),
+ TOBN(0x3db0b217, 0x5f87b1c1), TOBN(0xcc334771, 0x102a6db5)}},
+ {{TOBN(0xd99de954, 0x2f770fb1), TOBN(0x97c1c620, 0x4cd7535e),
+ TOBN(0xd3b6c448, 0x3f09cefc), TOBN(0xd725af15, 0x5a63b4f8)},
+ {TOBN(0x0c95d24f, 0xc01e20ec), TOBN(0xdfd37494, 0x9ae7121f),
+ TOBN(0x7d6ddb72, 0xec77b7ec), TOBN(0xfe079d3b, 0x0353a4ae)}},
+ {{TOBN(0x3066e70a, 0x2e6ac8d2), TOBN(0x9c6b5a43, 0x106e5c05),
+ TOBN(0x52d3c6f5, 0xede59b8c), TOBN(0x30d6a5c3, 0xfccec9ae)},
+ {TOBN(0xedec7c22, 0x4fc0a9ef), TOBN(0x190ff083, 0x95c16ced),
+ TOBN(0xbe12ec8f, 0x94de0fde), TOBN(0x0d131ab8, 0x852d3433)}},
+ {{TOBN(0x42ace07e, 0x85701291), TOBN(0x94793ed9, 0x194061a8),
+ TOBN(0x30e83ed6, 0xd7f4a485), TOBN(0x9eec7269, 0xf9eeff4d)},
+ {TOBN(0x90acba59, 0x0c9d8005), TOBN(0x5feca458, 0x1e79b9d1),
+ TOBN(0x8fbe5427, 0x1d506a1e), TOBN(0xa32b2c8e, 0x2439cfa7)}},
+ {{TOBN(0x1671c173, 0x73dd0b4e), TOBN(0x37a28214, 0x44a054c6),
+ TOBN(0x81760a1b, 0x4e8b53f1), TOBN(0xa6c04224, 0xf9f93b9e)},
+ {TOBN(0x18784b34, 0xcf671e3c), TOBN(0x81bbecd2, 0xcda9b994),
+ TOBN(0x38831979, 0xb2ab3848), TOBN(0xef54feb7, 0xf2e03c2d)}},
+ {{TOBN(0xcf197ca7, 0xfb8088fa), TOBN(0x01427247, 0x4ddc96c5),
+ TOBN(0xa2d2550a, 0x30777176), TOBN(0x53469898, 0x4d0cf71d)},
+ {TOBN(0x6ce937b8, 0x3a2aaac6), TOBN(0xe9f91dc3, 0x5af38d9b),
+ TOBN(0x2598ad83, 0xc8bf2899), TOBN(0x8e706ac9, 0xb5536c16)}},
+ {{TOBN(0x40dc7495, 0xf688dc98), TOBN(0x26490cd7, 0x124c4afc),
+ TOBN(0xe651ec84, 0x1f18775c), TOBN(0x393ea6c3, 0xb4fdaf4a)},
+ {TOBN(0x1e1f3343, 0x7f338e0d), TOBN(0x39fb832b, 0x6053e7b5),
+ TOBN(0x46e702da, 0x619e14d5), TOBN(0x859cacd1, 0xcdeef6e0)}},
+ {{TOBN(0x63b99ce7, 0x4462007d), TOBN(0xb8ab48a5, 0x4cb5f5b7),
+ TOBN(0x9ec673d2, 0xf55edde7), TOBN(0xd1567f74, 0x8cfaefda)},
+ {TOBN(0x46381b6b, 0x0887bcec), TOBN(0x694497ce, 0xe178f3c2),
+ TOBN(0x5e6525e3, 0x1e6266cb), TOBN(0x5931de26, 0x697d6413)}},
+ {{TOBN(0x87f8df7c, 0x0e58d493), TOBN(0xb1ae5ed0, 0x58b73f12),
+ TOBN(0xc368f784, 0xdea0c34d), TOBN(0x9bd0a120, 0x859a91a0)},
+ {TOBN(0xb00d88b7, 0xcc863c68), TOBN(0x3a1cc11e, 0x3d1f4d65),
+ TOBN(0xea38e0e7, 0x0aa85593), TOBN(0x37f13e98, 0x7dc4aee8)}},
+ {{TOBN(0x10d38667, 0xbc947bad), TOBN(0x738e07ce, 0x2a36ee2e),
+ TOBN(0xc93470cd, 0xc577fcac), TOBN(0xdee1b616, 0x2782470d)},
+ {TOBN(0x36a25e67, 0x2e793d12), TOBN(0xd6aa6cae, 0xe0f186da),
+ TOBN(0x474d0fd9, 0x80e07af7), TOBN(0xf7cdc47d, 0xba8a5cd4)}},
+ {{TOBN(0x28af6d9d, 0xab15247f), TOBN(0x7c789c10, 0x493a537f),
+ TOBN(0x7ac9b110, 0x23a334e7), TOBN(0x0236ac09, 0x12c9c277)},
+ {TOBN(0xa7e5bd25, 0x1d7a5144), TOBN(0x098b9c2a, 0xf13ec4ec),
+ TOBN(0x3639daca, 0xd3f0abca), TOBN(0x642da81a, 0xa23960f9)}},
+ {{TOBN(0x7d2e5c05, 0x4f7269b1), TOBN(0xfcf30777, 0xe287c385),
+ TOBN(0x10edc84f, 0xf2a46f21), TOBN(0x35441757, 0x4f43fa36)},
+ {TOBN(0xf1327899, 0xfd703431), TOBN(0xa438d7a6, 0x16dd587a),
+ TOBN(0x65c34c57, 0xe9c8352d), TOBN(0xa728edab, 0x5cc5a24e)}},
+ {{TOBN(0xaed78abc, 0x42531689), TOBN(0x0a51a0e8, 0x010963ef),
+ TOBN(0x5776fa0a, 0xd717d9b3), TOBN(0xf356c239, 0x7dd3428b)},
+ {TOBN(0x29903fff, 0x8d3a3dac), TOBN(0x409597fa, 0x3d94491f),
+ TOBN(0x4cd7a5ff, 0xbf4a56a4), TOBN(0xe5096474, 0x8adab462)}},
+ {{TOBN(0xa97b5126, 0x5c3427b0), TOBN(0x6401405c, 0xd282c9bd),
+ TOBN(0x3629f8d7, 0x222c5c45), TOBN(0xb1c02c16, 0xe8d50aed)},
+ {TOBN(0xbea2ed75, 0xd9635bc9), TOBN(0x226790c7, 0x6e24552f),
+ TOBN(0x3c33f2a3, 0x65f1d066), TOBN(0x2a43463e, 0x6dfccc2e)}},
+ {{TOBN(0x8cc3453a, 0xdb483761), TOBN(0xe7cc6085, 0x65d5672b),
+ TOBN(0x277ed6cb, 0xde3efc87), TOBN(0x19f2f368, 0x69234eaf)},
+ {TOBN(0x9aaf4317, 0x5c0b800b), TOBN(0x1f1e7c89, 0x8b6da6e2),
+ TOBN(0x6cfb4715, 0xb94ec75e), TOBN(0xd590dd5f, 0x453118c2)}},
+ {{TOBN(0x14e49da1, 0x1f17a34c), TOBN(0x5420ab39, 0x235a1456),
+ TOBN(0xb7637241, 0x2f50363b), TOBN(0x7b15d623, 0xc3fabb6e)},
+ {TOBN(0xa0ef40b1, 0xe274e49c), TOBN(0x5cf50744, 0x96b1860a),
+ TOBN(0xd6583fbf, 0x66afe5a4), TOBN(0x44240510, 0xf47e3e9a)}},
+ {{TOBN(0x99254343, 0x11b2d595), TOBN(0xf1367499, 0xeec8df57),
+ TOBN(0x3cb12c61, 0x3e73dd05), TOBN(0xd248c033, 0x7dac102a)},
+ {TOBN(0xcf154f13, 0xa77739f5), TOBN(0xbf4288cb, 0x23d2af42),
+ TOBN(0xaa64c9b6, 0x32e4a1cf), TOBN(0xee8c07a8, 0xc8a208f3)}},
+ {{TOBN(0xe10d4999, 0x6fe8393f), TOBN(0x0f809a3f, 0xe91f3a32),
+ TOBN(0x61096d1c, 0x802f63c8), TOBN(0x289e1462, 0x57750d3d)},
+ {TOBN(0xed06167e, 0x9889feea), TOBN(0xd5c9c0e2, 0xe0993909),
+ TOBN(0x46fca0d8, 0x56508ac6), TOBN(0x91826047, 0x4f1b8e83)}},
+ {{TOBN(0x4f2c877a, 0x9a4a2751), TOBN(0x71bd0072, 0xcae6fead),
+ TOBN(0x38df8dcc, 0x06aa1941), TOBN(0x5a074b4c, 0x63beeaa8)},
+ {TOBN(0xd6d65934, 0xc1cec8ed), TOBN(0xa6ecb49e, 0xaabc03bd),
+ TOBN(0xaade91c2, 0xde8a8415), TOBN(0xcfb0efdf, 0x691136e0)}},
+ {{TOBN(0x11af45ee, 0x23ab3495), TOBN(0xa132df88, 0x0b77463d),
+ TOBN(0x8923c15c, 0x815d06f4), TOBN(0xc3ceb3f5, 0x0d61a436)},
+ {TOBN(0xaf52291d, 0xe88fb1da), TOBN(0xea057974, 0x1da12179),
+ TOBN(0xb0d7218c, 0xd2fef720), TOBN(0x6c0899c9, 0x8e1d8845)}},
+ {{TOBN(0x98157504, 0x752ddad7), TOBN(0xd60bd74f, 0xa1a68a97),
+ TOBN(0x7047a3a9, 0xf658fb99), TOBN(0x1f5d86d6, 0x5f8511e4)},
+ {TOBN(0xb8a4bc42, 0x4b5a6d88), TOBN(0x69eb2c33, 0x1abefa7d),
+ TOBN(0x95bf39e8, 0x13c9c510), TOBN(0xf571960a, 0xd48aab43)}},
+ {{TOBN(0x7e8cfbcf, 0x704e23c6), TOBN(0xc71b7d22, 0x28aaa65b),
+ TOBN(0xa041b2bd, 0x245e3c83), TOBN(0x69b98834, 0xd21854ff)},
+ {TOBN(0x89d227a3, 0x963bfeec), TOBN(0x99947aaa, 0xde7da7cb),
+ TOBN(0x1d9ee9db, 0xee68a9b1), TOBN(0x0a08f003, 0x698ec368)}},
+ {{TOBN(0xe9ea4094, 0x78ef2487), TOBN(0xc8d2d415, 0x02cfec26),
+ TOBN(0xc52f9a6e, 0xb7dcf328), TOBN(0x0ed489e3, 0x85b6a937)},
+ {TOBN(0x9b94986b, 0xbef3366e), TOBN(0x0de59c70, 0xedddddb8),
+ TOBN(0xffdb748c, 0xeadddbe2), TOBN(0x9b9784bb, 0x8266ea40)}},
+ {{TOBN(0x142b5502, 0x1a93507a), TOBN(0xb4cd1187, 0x8d3c06cf),
+ TOBN(0xdf70e76a, 0x91ec3f40), TOBN(0x484e81ad, 0x4e7553c2)},
+ {TOBN(0x830f87b5, 0x272e9d6e), TOBN(0xea1c93e5, 0xc6ff514a),
+ TOBN(0x67cc2adc, 0xc4192a8e), TOBN(0xc77e27e2, 0x42f4535a)}},
+ {{TOBN(0x9cdbab36, 0xd2b713c5), TOBN(0x86274ea0, 0xcf7b0cd3),
+ TOBN(0x784680f3, 0x09af826b), TOBN(0xbfcc837a, 0x0c72dea3)},
+ {TOBN(0xa8bdfe9d, 0xd6529b73), TOBN(0x708aa228, 0x63a88002),
+ TOBN(0x6c7a9a54, 0xc91d45b9), TOBN(0xdf1a38bb, 0xfd004f56)}},
+ {{TOBN(0x2e8c9a26, 0xb8bad853), TOBN(0x2d52cea3, 0x3723eae7),
+ TOBN(0x054d6d81, 0x56ca2830), TOBN(0xa3317d14, 0x9a8dc411)},
+ {TOBN(0xa08662fe, 0xfd4ddeda), TOBN(0xed2a153a, 0xb55d792b),
+ TOBN(0x7035c16a, 0xbfc6e944), TOBN(0xb6bc5834, 0x00171cf3)}},
+ {{TOBN(0xe27152b3, 0x83d102b6), TOBN(0xfe695a47, 0x0646b848),
+ TOBN(0xa5bb09d8, 0x916e6d37), TOBN(0xb4269d64, 0x0d17015e)},
+ {TOBN(0x8d8156a1, 0x0a1d2285), TOBN(0xfeef6c51, 0x46d26d72),
+ TOBN(0x9dac57c8, 0x4c5434a7), TOBN(0x0282e5be, 0x59d39e31)}},
+ {{TOBN(0xedfff181, 0x721c486d), TOBN(0x301baf10, 0xbc58824e),
+ TOBN(0x8136a6aa, 0x00570031), TOBN(0x55aaf78c, 0x1cddde68)},
+ {TOBN(0x26829371, 0x59c63952), TOBN(0x3a3bd274, 0x8bc25baf),
+ TOBN(0xecdf8657, 0xb7e52dc3), TOBN(0x2dd8c087, 0xfd78e6c8)}},
+ {{TOBN(0x20553274, 0xf5531461), TOBN(0x8b4a1281, 0x5d95499b),
+ TOBN(0xe2c8763a, 0x1a80f9d2), TOBN(0xd1dbe32b, 0x4ddec758)},
+ {TOBN(0xaf12210d, 0x30c34169), TOBN(0xba74a953, 0x78baa533),
+ TOBN(0x3d133c6e, 0xa438f254), TOBN(0xa431531a, 0x201bef5b)}},
+ {{TOBN(0x15295e22, 0xf669d7ec), TOBN(0xca374f64, 0x357fb515),
+ TOBN(0x8a8406ff, 0xeaa3fdb3), TOBN(0x106ae448, 0xdf3f2da8)},
+ {TOBN(0x8f9b0a90, 0x33c8e9a1), TOBN(0x234645e2, 0x71ad5885),
+ TOBN(0x3d083224, 0x1c0aed14), TOBN(0xf10a7d3e, 0x7a942d46)}},
+ {{TOBN(0x7c11deee, 0x40d5c9be), TOBN(0xb2bae7ff, 0xba84ed98),
+ TOBN(0x93e97139, 0xaad58ddd), TOBN(0x3d872796, 0x3f6d1fa3)},
+ {TOBN(0x483aca81, 0x8569ff13), TOBN(0x8b89a5fb, 0x9a600f72),
+ TOBN(0x4cbc27c3, 0xc06f2b86), TOBN(0x22130713, 0x63ad9c0b)}},
+ {{TOBN(0xb5358b1e, 0x48ac2840), TOBN(0x18311294, 0xecba9477),
+ TOBN(0xda58f990, 0xa6946b43), TOBN(0x3098baf9, 0x9ab41819)},
+ {TOBN(0x66c4c158, 0x4198da52), TOBN(0xab4fc17c, 0x146bfd1b),
+ TOBN(0x2f0a4c3c, 0xbf36a908), TOBN(0x2ae9e34b, 0x58cf7838)}},
+ {{TOBN(0xf411529e, 0x3fa11b1f), TOBN(0x21e43677, 0x974af2b4),
+ TOBN(0x7c20958e, 0xc230793b), TOBN(0x710ea885, 0x16e840f3)},
+ {TOBN(0xfc0b21fc, 0xc5dc67cf), TOBN(0x08d51647, 0x88405718),
+ TOBN(0xd955c21f, 0xcfe49eb7), TOBN(0x9722a5d5, 0x56dd4a1f)}},
+ {{TOBN(0xc9ef50e2, 0xc861baa5), TOBN(0xc0c21a5d, 0x9505ac3e),
+ TOBN(0xaf6b9a33, 0x8b7c063f), TOBN(0xc6370339, 0x2f4779c1)},
+ {TOBN(0x22df99c7, 0x638167c3), TOBN(0xfe6ffe76, 0x795db30c),
+ TOBN(0x2b822d33, 0xa4854989), TOBN(0xfef031dd, 0x30563aa5)}},
+ {{TOBN(0x16b09f82, 0xd57c667f), TOBN(0xc70312ce, 0xcc0b76f1),
+ TOBN(0xbf04a9e6, 0xc9118aec), TOBN(0x82fcb419, 0x3409d133)},
+ {TOBN(0x1a8ab385, 0xab45d44d), TOBN(0xfba07222, 0x617b83a3),
+ TOBN(0xb05f50dd, 0x58e81b52), TOBN(0x1d8db553, 0x21ce5aff)}},
+ {{TOBN(0x3097b8d4, 0xe344a873), TOBN(0x7d8d116d, 0xfe36d53e),
+ TOBN(0x6db22f58, 0x7875e750), TOBN(0x2dc5e373, 0x43e144ea)},
+ {TOBN(0xc05f32e6, 0xe799eb95), TOBN(0xe9e5f4df, 0x6899e6ec),
+ TOBN(0xbdc3bd68, 0x1fab23d5), TOBN(0xb72b8ab7, 0x73af60e6)}},
+ {{TOBN(0x8db27ae0, 0x2cecc84a), TOBN(0x600016d8, 0x7bdb871c),
+ TOBN(0x42a44b13, 0xd7c46f58), TOBN(0xb8919727, 0xc3a77d39)},
+ {TOBN(0xcfc6bbbd, 0xdafd6088), TOBN(0x1a740146, 0x6bd20d39),
+ TOBN(0x8c747abd, 0x98c41072), TOBN(0x4c91e765, 0xbdf68ea1)}},
+ {{TOBN(0x7c95e5ca, 0x08819a78), TOBN(0xcf48b729, 0xc9587921),
+ TOBN(0x091c7c5f, 0xdebbcc7d), TOBN(0x6f287404, 0xf0e05149)},
+ {TOBN(0xf83b5ac2, 0x26cd44ec), TOBN(0x88ae32a6, 0xcfea250e),
+ TOBN(0x6ac5047a, 0x1d06ebc5), TOBN(0xc7e550b4, 0xd434f781)}},
+ {{TOBN(0x61ab1cf2, 0x5c727bd2), TOBN(0x2e4badb1, 0x1cf915b0),
+ TOBN(0x1b4dadec, 0xf69d3920), TOBN(0xe61b1ca6, 0xf14c1dfe)},
+ {TOBN(0x90b479cc, 0xbd6bd51f), TOBN(0x8024e401, 0x8045ec30),
+ TOBN(0xcab29ca3, 0x25ef0e62), TOBN(0x4f2e9416, 0x49e4ebc0)}},
+ {{TOBN(0x45eb40ec, 0x0ccced58), TOBN(0x25cd4b9c, 0x0da44f98),
+ TOBN(0x43e06458, 0x871812c6), TOBN(0x99f80d55, 0x16cef651)},
+ {TOBN(0x571340c9, 0xce6dc153), TOBN(0x138d5117, 0xd8665521),
+ TOBN(0xacdb45bc, 0x4e07014d), TOBN(0x2f34bb38, 0x84b60b91)}},
+ {{TOBN(0xf44a4fd2, 0x2ae8921e), TOBN(0xb039288e, 0x892ba1e2),
+ TOBN(0x9da50174, 0xb1c180b2), TOBN(0x6b70ab66, 0x1693dc87)},
+ {TOBN(0x7e9babc9, 0xe7057481), TOBN(0x4581ddef, 0x9c80dc41),
+ TOBN(0x0c890da9, 0x51294682), TOBN(0x0b5629d3, 0x3f4736e5)}},
+ {{TOBN(0x2340c79e, 0xb06f5b41), TOBN(0xa42e84ce, 0x4e243469),
+ TOBN(0xf9a20135, 0x045a71a9), TOBN(0xefbfb415, 0xd27b6fb6)},
+ {TOBN(0x25ebea23, 0x9d33cd6f), TOBN(0x9caedb88, 0xaa6c0af8),
+ TOBN(0x53dc7e9a, 0xd9ce6f96), TOBN(0x3897f9fd, 0x51e0b15a)}},
+ {{TOBN(0xf51cb1f8, 0x8e5d788e), TOBN(0x1aec7ba8, 0xe1d490ee),
+ TOBN(0x265991e0, 0xcc58cb3c), TOBN(0x9f306e8c, 0x9fc3ad31)},
+ {TOBN(0x5fed006e, 0x5040a0ac), TOBN(0xca9d5043, 0xfb476f2e),
+ TOBN(0xa19c06e8, 0xbeea7a23), TOBN(0xd2865801, 0x0edabb63)}},
+ {{TOBN(0xdb92293f, 0x6967469a), TOBN(0x2894d839, 0x8d8a8ed8),
+ TOBN(0x87c9e406, 0xbbc77122), TOBN(0x8671c6f1, 0x2ea3a26a)},
+ {TOBN(0xe42df8d6, 0xd7de9853), TOBN(0x2e3ce346, 0xb1f2bcc7),
+ TOBN(0xda601dfc, 0x899d50cf), TOBN(0xbfc913de, 0xfb1b598f)}},
+ {{TOBN(0x81c4909f, 0xe61f7908), TOBN(0x192e304f, 0x9bbc7b29),
+ TOBN(0xc3ed8738, 0xc104b338), TOBN(0xedbe9e47, 0x783f5d61)},
+ {TOBN(0x0c06e9be, 0x2db30660), TOBN(0xda3e613f, 0xc0eb7d8e),
+ TOBN(0xd8fa3e97, 0x322e096e), TOBN(0xfebd91e8, 0xd336e247)}},
+ {{TOBN(0x8f13ccc4, 0xdf655a49), TOBN(0xa9e00dfc, 0x5eb20210),
+ TOBN(0x84631d0f, 0xc656b6ea), TOBN(0x93a058cd, 0xd8c0d947)},
+ {TOBN(0x6846904a, 0x67bd3448), TOBN(0x4a3d4e1a, 0xf394fd5c),
+ TOBN(0xc102c1a5, 0xdb225f52), TOBN(0xe3455bba, 0xfc4f5e9a)}},
+ {{TOBN(0x6b36985b, 0x4b9ad1ce), TOBN(0xa9818536, 0x5bb7f793),
+ TOBN(0x6c25e1d0, 0x48b1a416), TOBN(0x1381dd53, 0x3c81bee7)},
+ {TOBN(0xd2a30d61, 0x7a4a7620), TOBN(0xc8412926, 0x39b8944c),
+ TOBN(0x3c1c6fbe, 0x7a97c33a), TOBN(0x941e541d, 0x938664e7)}},
+ {{TOBN(0x417499e8, 0x4a34f239), TOBN(0x15fdb83c, 0xb90402d5),
+ TOBN(0xb75f46bf, 0x433aa832), TOBN(0xb61e15af, 0x63215db1)},
+ {TOBN(0xaabe59d4, 0xa127f89a), TOBN(0x5d541e0c, 0x07e816da),
+ TOBN(0xaaba0659, 0xa618b692), TOBN(0x55327733, 0x17266026)}},
+ {{TOBN(0xaf53a0fc, 0x95f57552), TOBN(0x32947650, 0x6cacb0c9),
+ TOBN(0x253ff58d, 0xc821be01), TOBN(0xb0309531, 0xa06f1146)},
+ {TOBN(0x59bbbdf5, 0x05c2e54d), TOBN(0x158f27ad, 0x26e8dd22),
+ TOBN(0xcc5b7ffb, 0x397e1e53), TOBN(0xae03f65b, 0x7fc1e50d)}},
+ {{TOBN(0xa9784ebd, 0x9c95f0f9), TOBN(0x5ed9deb2, 0x24640771),
+ TOBN(0x31244af7, 0x035561c4), TOBN(0x87332f3a, 0x7ee857de)},
+ {TOBN(0x09e16e9e, 0x2b9e0d88), TOBN(0x52d910f4, 0x56a06049),
+ TOBN(0x507ed477, 0xa9592f48), TOBN(0x85cb917b, 0x2365d678)}},
+ {{TOBN(0xf8511c93, 0x4c8998d1), TOBN(0x2186a3f1, 0x730ea58f),
+ TOBN(0x50189626, 0xb2029db0), TOBN(0x9137a6d9, 0x02ceb75a)},
+ {TOBN(0x2fe17f37, 0x748bc82c), TOBN(0x87c2e931, 0x80469f8c),
+ TOBN(0x850f71cd, 0xbf891aa2), TOBN(0x0ca1b89b, 0x75ec3d8d)}},
+ {{TOBN(0x516c43aa, 0x5e1cd3cd), TOBN(0x89397808, 0x9a887c28),
+ TOBN(0x0059c699, 0xddea1f9f), TOBN(0x7737d6fa, 0x8e6868f7)},
+ {TOBN(0x6d93746a, 0x60f1524b), TOBN(0x36985e55, 0xba052aa7),
+ TOBN(0x41b1d322, 0xed923ea5), TOBN(0x3429759f, 0x25852a11)}},
+ {{TOBN(0xbeca6ec3, 0x092e9f41), TOBN(0x3a238c66, 0x62256bbd),
+ TOBN(0xd82958ea, 0x70ad487d), TOBN(0x4ac8aaf9, 0x65610d93)},
+ {TOBN(0x3fa101b1, 0x5e4ccab0), TOBN(0x9bf430f2, 0x9de14bfb),
+ TOBN(0xa10f5cc6, 0x6531899d), TOBN(0x590005fb, 0xea8ce17d)}},
+ {{TOBN(0xc437912f, 0x24544cb6), TOBN(0x9987b71a, 0xd79ac2e3),
+ TOBN(0x13e3d9dd, 0xc058a212), TOBN(0x00075aac, 0xd2de9606)},
+ {TOBN(0x80ab508b, 0x6cac8369), TOBN(0x87842be7, 0xf54f6c89),
+ TOBN(0xa7ad663d, 0x6bc532a4), TOBN(0x67813de7, 0x78a91bc8)}},
+ {{TOBN(0x5dcb61ce, 0xc3427239), TOBN(0x5f3c7cf0, 0xc56934d9),
+ TOBN(0xc079e0fb, 0xe3191591), TOBN(0xe40896bd, 0xb01aada7)},
+ {TOBN(0x8d466791, 0x0492d25f), TOBN(0x8aeb30c9, 0xe7408276),
+ TOBN(0xe9437495, 0x9287aacc), TOBN(0x23d4708d, 0x79fe03d4)}},
+ {{TOBN(0x8cda9cf2, 0xd0c05199), TOBN(0x502fbc22, 0xfae78454),
+ TOBN(0xc0bda9df, 0xf572a182), TOBN(0x5f9b71b8, 0x6158b372)},
+ {TOBN(0xe0f33a59, 0x2b82dd07), TOBN(0x76302735, 0x9523032e),
+ TOBN(0x7fe1a721, 0xc4505a32), TOBN(0x7b6e3e82, 0xf796409f)}}},
+ {{{TOBN(0xe3417bc0, 0x35d0b34a), TOBN(0x440b386b, 0x8327c0a7),
+ TOBN(0x8fb7262d, 0xac0362d1), TOBN(0x2c41114c, 0xe0cdf943)},
+ {TOBN(0x2ba5cef1, 0xad95a0b1), TOBN(0xc09b37a8, 0x67d54362),
+ TOBN(0x26d6cdd2, 0x01e486c9), TOBN(0x20477abf, 0x42ff9297)}},
+ {{TOBN(0xa004dcb3, 0x292a9287), TOBN(0xddc15cf6, 0x77b092c7),
+ TOBN(0x083a8464, 0x806c0605), TOBN(0x4a68df70, 0x3db997b0)},
+ {TOBN(0x9c134e45, 0x05bf7dd0), TOBN(0xa4e63d39, 0x8ccf7f8c),
+ TOBN(0xa6e6517f, 0x41b5f8af), TOBN(0xaa8b9342, 0xad7bc1cc)}},
+ {{TOBN(0x126f35b5, 0x1e706ad9), TOBN(0xb99cebb4, 0xc3a9ebdf),
+ TOBN(0xa75389af, 0xbf608d90), TOBN(0x76113c4f, 0xc6c89858)},
+ {TOBN(0x80de8eb0, 0x97e2b5aa), TOBN(0x7e1022cc, 0x63b91304),
+ TOBN(0x3bdab605, 0x6ccc066c), TOBN(0x33cbb144, 0xb2edf900)}},
+ {{TOBN(0xc4176471, 0x7af715d2), TOBN(0xe2f7f594, 0xd0134a96),
+ TOBN(0x2c1873ef, 0xa41ec956), TOBN(0xe4e7b4f6, 0x77821304)},
+ {TOBN(0xe5c8ff97, 0x88d5374a), TOBN(0x2b915e63, 0x80823d5b),
+ TOBN(0xea6bc755, 0xb2ee8fe2), TOBN(0x6657624c, 0xe7112651)}},
+ {{TOBN(0x157af101, 0xdace5aca), TOBN(0xc4fdbcf2, 0x11a6a267),
+ TOBN(0xdaddf340, 0xc49c8609), TOBN(0x97e49f52, 0xe9604a65)},
+ {TOBN(0x9be8e790, 0x937e2ad5), TOBN(0x846e2508, 0x326e17f1),
+ TOBN(0x3f38007a, 0x0bbbc0dc), TOBN(0xcf03603f, 0xb11e16d6)}},
+ {{TOBN(0xd6f800e0, 0x7442f1d5), TOBN(0x475607d1, 0x66e0e3ab),
+ TOBN(0x82807f16, 0xb7c64047), TOBN(0x8858e1e3, 0xa749883d)},
+ {TOBN(0x5859120b, 0x8231ee10), TOBN(0x1b80e7eb, 0x638a1ece),
+ TOBN(0xcb72525a, 0xc6aa73a4), TOBN(0xa7cdea3d, 0x844423ac)}},
+ {{TOBN(0x5ed0c007, 0xf8ae7c38), TOBN(0x6db07a5c, 0x3d740192),
+ TOBN(0xbe5e9c2a, 0x5fe36db3), TOBN(0xd5b9d57a, 0x76e95046)},
+ {TOBN(0x54ac32e7, 0x8eba20f2), TOBN(0xef11ca8f, 0x71b9a352),
+ TOBN(0x305e373e, 0xff98a658), TOBN(0xffe5a100, 0x823eb667)}},
+ {{TOBN(0x57477b11, 0xe51732d2), TOBN(0xdfd6eb28, 0x2538fc0e),
+ TOBN(0x5c43b0cc, 0x3b39eec5), TOBN(0x6af12778, 0xcb36cc57)},
+ {TOBN(0x70b0852d, 0x06c425ae), TOBN(0x6df92f8c, 0x5c221b9b),
+ TOBN(0x6c8d4f9e, 0xce826d9c), TOBN(0xf59aba7b, 0xb49359c3)}},
+ {{TOBN(0x5c8ed8d5, 0xda64309d), TOBN(0x61a6de56, 0x91b30704),
+ TOBN(0xd6b52f6a, 0x2f9b5808), TOBN(0x0eee4194, 0x98c958a7)},
+ {TOBN(0xcddd9aab, 0x771e4caa), TOBN(0x83965dfd, 0x78bc21be),
+ TOBN(0x02affce3, 0xb3b504f5), TOBN(0x30847a21, 0x561c8291)}},
+ {{TOBN(0xd2eb2cf1, 0x52bfda05), TOBN(0xe0e4c4e9, 0x6197b98c),
+ TOBN(0x1d35076c, 0xf8a1726f), TOBN(0x6c06085b, 0x2db11e3d)},
+ {TOBN(0x15c0c4d7, 0x4463ba14), TOBN(0x9d292f83, 0x0030238c),
+ TOBN(0x1311ee8b, 0x3727536d), TOBN(0xfeea86ef, 0xbeaedc1e)}},
+ {{TOBN(0xb9d18cd3, 0x66131e2e), TOBN(0xf31d974f, 0x80fe2682),
+ TOBN(0xb6e49e0f, 0xe4160289), TOBN(0x7c48ec0b, 0x08e92799)},
+ {TOBN(0x818111d8, 0xd1989aa7), TOBN(0xb34fa0aa, 0xebf926f9),
+ TOBN(0xdb5fe2f5, 0xa245474a), TOBN(0xf80a6ebb, 0x3c7ca756)}},
+ {{TOBN(0xa7f96054, 0xafa05dd8), TOBN(0x26dfcf21, 0xfcaf119e),
+ TOBN(0xe20ef2e3, 0x0564bb59), TOBN(0xef4dca50, 0x61cb02b8)},
+ {TOBN(0xcda7838a, 0x65d30672), TOBN(0x8b08d534, 0xfd657e86),
+ TOBN(0x4c5b4395, 0x46d595c8), TOBN(0x39b58725, 0x425cb836)}},
+ {{TOBN(0x8ea61059, 0x3de9abe3), TOBN(0x40434881, 0x9cdc03be),
+ TOBN(0x9b261245, 0xcfedce8c), TOBN(0x78c318b4, 0xcf5234a1)},
+ {TOBN(0x510bcf16, 0xfde24c99), TOBN(0x2a77cb75, 0xa2c2ff5d),
+ TOBN(0x9c895c2b, 0x27960fb4), TOBN(0xd30ce975, 0xb0eda42b)}},
+ {{TOBN(0xfda85393, 0x1a62cc26), TOBN(0x23c69b96, 0x50c0e052),
+ TOBN(0xa227df15, 0xbfc633f3), TOBN(0x2ac78848, 0x1bae7d48)},
+ {TOBN(0x487878f9, 0x187d073d), TOBN(0x6c2be919, 0x967f807d),
+ TOBN(0x765861d8, 0x336e6d8f), TOBN(0x88b8974c, 0xce528a43)}},
+ {{TOBN(0x09521177, 0xff57d051), TOBN(0x2ff38037, 0xfb6a1961),
+ TOBN(0xfc0aba74, 0xa3d76ad4), TOBN(0x7c764803, 0x25a7ec17)},
+ {TOBN(0x7532d75f, 0x48879bc8), TOBN(0xea7eacc0, 0x58ce6bc1),
+ TOBN(0xc82176b4, 0x8e896c16), TOBN(0x9a30e0b2, 0x2c750fed)}},
+ {{TOBN(0xc37e2c2e, 0x421d3aa4), TOBN(0xf926407c, 0xe84fa840),
+ TOBN(0x18abc03d, 0x1454e41c), TOBN(0x26605ecd, 0x3f7af644)},
+ {TOBN(0x242341a6, 0xd6a5eabf), TOBN(0x1edb84f4, 0x216b668e),
+ TOBN(0xd836edb8, 0x04010102), TOBN(0x5b337ce7, 0x945e1d8c)}},
+ {{TOBN(0xd2075c77, 0xc055dc14), TOBN(0x2a0ffa25, 0x81d89cdf),
+ TOBN(0x8ce815ea, 0x6ffdcbaf), TOBN(0xa3428878, 0xfb648867)},
+ {TOBN(0x277699cf, 0x884655fb), TOBN(0xfa5b5bd6, 0x364d3e41),
+ TOBN(0x01f680c6, 0x441e1cb7), TOBN(0x3fd61e66, 0xb70a7d67)}},
+ {{TOBN(0x666ba2dc, 0xcc78cf66), TOBN(0xb3018174, 0x6fdbff77),
+ TOBN(0x8d4dd0db, 0x168d4668), TOBN(0x259455d0, 0x1dab3a2a)},
+ {TOBN(0xf58564c5, 0xcde3acec), TOBN(0x77141925, 0x13adb276),
+ TOBN(0x527d725d, 0x8a303f65), TOBN(0x55deb6c9, 0xe6f38f7b)}},
+ {{TOBN(0xfd5bb657, 0xb1fa70fb), TOBN(0xfa07f50f, 0xd8073a00),
+ TOBN(0xf72e3aa7, 0xbca02500), TOBN(0xf68f895d, 0x9975740d)},
+ {TOBN(0x30112060, 0x5cae2a6a), TOBN(0x01bd7218, 0x02874842),
+ TOBN(0x3d423891, 0x7ce47bd3), TOBN(0xa66663c1, 0x789544f6)}},
+ {{TOBN(0x864d05d7, 0x3272d838), TOBN(0xe22924f9, 0xfa6295c5),
+ TOBN(0x8189593f, 0x6c2fda32), TOBN(0x330d7189, 0xb184b544)},
+ {TOBN(0x79efa62c, 0xbde1f714), TOBN(0x35771c94, 0xe5cb1a63),
+ TOBN(0x2f4826b8, 0x641c8332), TOBN(0x00a894fb, 0xc8cee854)}},
+ {{TOBN(0xb4b9a39b, 0x36194d40), TOBN(0xe857a7c5, 0x77612601),
+ TOBN(0xf4209dd2, 0x4ecf2f58), TOBN(0x82b9e66d, 0x5a033487)},
+ {TOBN(0xc1e36934, 0xe4e8b9dd), TOBN(0xd2372c9d, 0xa42377d7),
+ TOBN(0x51dc94c7, 0x0e3ae43b), TOBN(0x4c57761e, 0x04474f6f)}},
+ {{TOBN(0xdcdacd0a, 0x1058a318), TOBN(0x369cf3f5, 0x78053a9a),
+ TOBN(0xc6c3de50, 0x31c68de2), TOBN(0x4653a576, 0x3c4b6d9f)},
+ {TOBN(0x1688dd5a, 0xaa4e5c97), TOBN(0x5be80aa1, 0xb7ab3c74),
+ TOBN(0x70cefe7c, 0xbc65c283), TOBN(0x57f95f13, 0x06867091)}},
+ {{TOBN(0xa39114e2, 0x4415503b), TOBN(0xc08ff7c6, 0x4cbb17e9),
+ TOBN(0x1eff674d, 0xd7dec966), TOBN(0x6d4690af, 0x53376f63)},
+ {TOBN(0xff6fe32e, 0xea74237b), TOBN(0xc436d17e, 0xcd57508e),
+ TOBN(0x15aa28e1, 0xedcc40fe), TOBN(0x0d769c04, 0x581bbb44)}},
+ {{TOBN(0xc240b6de, 0x34eaacda), TOBN(0xd9e116e8, 0x2ba0f1de),
+ TOBN(0xcbe45ec7, 0x79438e55), TOBN(0x91787c9d, 0x96f752d7)},
+ {TOBN(0x897f532b, 0xf129ac2f), TOBN(0xd307b7c8, 0x5a36e22c),
+ TOBN(0x91940675, 0x749fb8f3), TOBN(0xd14f95d0, 0x157fdb28)}},
+ {{TOBN(0xfe51d029, 0x6ae55043), TOBN(0x8931e98f, 0x44a87de1),
+ TOBN(0xe57f1cc6, 0x09e4fee2), TOBN(0x0d063b67, 0x4e072d92)},
+ {TOBN(0x70a998b9, 0xed0e4316), TOBN(0xe74a736b, 0x306aca46),
+ TOBN(0xecf0fbf2, 0x4fda97c7), TOBN(0xa40f65cb, 0x3e178d93)}},
+ {{TOBN(0x16253604, 0x16df4285), TOBN(0xb0c9babb, 0xd0c56ae2),
+ TOBN(0x73032b19, 0xcfc5cfc3), TOBN(0xe497e5c3, 0x09752056)},
+ {TOBN(0x12096bb4, 0x164bda96), TOBN(0x1ee42419, 0xa0b74da1),
+ TOBN(0x8fc36243, 0x403826ba), TOBN(0x0c8f0069, 0xdc09e660)}},
+ {{TOBN(0x8667e981, 0xc27253c9), TOBN(0x05a6aefb, 0x92b36a45),
+ TOBN(0xa62c4b36, 0x9cb7bb46), TOBN(0x8394f375, 0x11f7027b)},
+ {TOBN(0x747bc79c, 0x5f109d0f), TOBN(0xcad88a76, 0x5b8cc60a),
+ TOBN(0x80c5a66b, 0x58f09e68), TOBN(0xe753d451, 0xf6127eac)}},
+ {{TOBN(0xc44b74a1, 0x5b0ec6f5), TOBN(0x47989fe4, 0x5289b2b8),
+ TOBN(0x745f8484, 0x58d6fc73), TOBN(0xec362a6f, 0xf61c70ab)},
+ {TOBN(0x070c98a7, 0xb3a8ad41), TOBN(0x73a20fc0, 0x7b63db51),
+ TOBN(0xed2c2173, 0xf44c35f4), TOBN(0x8a56149d, 0x9acc9dca)}},
+ {{TOBN(0x98f17881, 0x9ac6e0f4), TOBN(0x360fdeaf, 0xa413b5ed),
+ TOBN(0x0625b8f4, 0xa300b0fd), TOBN(0xf1f4d76a, 0x5b3222d3)},
+ {TOBN(0x9d6f5109, 0x587f76b8), TOBN(0x8b4ee08d, 0x2317fdb5),
+ TOBN(0x88089bb7, 0x8c68b095), TOBN(0x95570e9a, 0x5808d9b9)}},
+ {{TOBN(0xa395c36f, 0x35d33ae7), TOBN(0x200ea123, 0x50bb5a94),
+ TOBN(0x20c789bd, 0x0bafe84b), TOBN(0x243ef52d, 0x0919276a)},
+ {TOBN(0x3934c577, 0xe23ae233), TOBN(0xb93807af, 0xa460d1ec),
+ TOBN(0xb72a53b1, 0xf8fa76a4), TOBN(0xd8914cb0, 0xc3ca4491)}},
+ {{TOBN(0x2e128494, 0x3fb42622), TOBN(0x3b2700ac, 0x500907d5),
+ TOBN(0xf370fb09, 0x1a95ec63), TOBN(0xf8f30be2, 0x31b6dfbd)},
+ {TOBN(0xf2b2f8d2, 0x69e55f15), TOBN(0x1fead851, 0xcc1323e9),
+ TOBN(0xfa366010, 0xd9e5eef6), TOBN(0x64d487b0, 0xe316107e)}},
+ {{TOBN(0x4c076b86, 0xd23ddc82), TOBN(0x03fd344c, 0x7e0143f0),
+ TOBN(0xa95362ff, 0x317af2c5), TOBN(0x0add3db7, 0xe18b7a4f)},
+ {TOBN(0x9c673e3f, 0x8260e01b), TOBN(0xfbeb49e5, 0x54a1cc91),
+ TOBN(0x91351bf2, 0x92f2e433), TOBN(0xc755e7ec, 0x851141eb)}},
+ {{TOBN(0xc9a95139, 0x29607745), TOBN(0x0ca07420, 0xa26f2b28),
+ TOBN(0xcb2790e7, 0x4bc6f9dd), TOBN(0x345bbb58, 0xadcaffc0)},
+ {TOBN(0xc65ea38c, 0xbe0f27a2), TOBN(0x67c24d7c, 0x641fcb56),
+ TOBN(0x2c25f0a7, 0xa9e2c757), TOBN(0x93f5cdb0, 0x16f16c49)}},
+ {{TOBN(0x2ca5a9d7, 0xc5ee30a1), TOBN(0xd1593635, 0xb909b729),
+ TOBN(0x804ce9f3, 0xdadeff48), TOBN(0xec464751, 0xb07c30c3)},
+ {TOBN(0x89d65ff3, 0x9e49af6a), TOBN(0xf2d6238a, 0x6f3d01bc),
+ TOBN(0x1095561e, 0x0bced843), TOBN(0x51789e12, 0xc8a13fd8)}},
+ {{TOBN(0xd633f929, 0x763231df), TOBN(0x46df9f7d, 0xe7cbddef),
+ TOBN(0x01c889c0, 0xcb265da8), TOBN(0xfce1ad10, 0xaf4336d2)},
+ {TOBN(0x8d110df6, 0xfc6a0a7e), TOBN(0xdd431b98, 0x6da425dc),
+ TOBN(0xcdc4aeab, 0x1834aabe), TOBN(0x84deb124, 0x8439b7fc)}},
+ {{TOBN(0x8796f169, 0x3c2a5998), TOBN(0x9b9247b4, 0x7947190d),
+ TOBN(0x55b9d9a5, 0x11597014), TOBN(0x7e9dd70d, 0x7b1566ee)},
+ {TOBN(0x94ad78f7, 0xcbcd5e64), TOBN(0x0359ac17, 0x9bd4c032),
+ TOBN(0x3b11baaf, 0x7cc222ae), TOBN(0xa6a6e284, 0xba78e812)}},
+ {{TOBN(0x8392053f, 0x24cea1a0), TOBN(0xc97bce4a, 0x33621491),
+ TOBN(0x7eb1db34, 0x35399ee9), TOBN(0x473f78ef, 0xece81ad1)},
+ {TOBN(0x41d72fe0, 0xf63d3d0d), TOBN(0xe620b880, 0xafab62fc),
+ TOBN(0x92096bc9, 0x93158383), TOBN(0x41a21357, 0x8f896f6c)}},
+ {{TOBN(0x1b5ee2fa, 0xc7dcfcab), TOBN(0x650acfde, 0x9546e007),
+ TOBN(0xc081b749, 0xb1b02e07), TOBN(0xda9e41a0, 0xf9eca03d)},
+ {TOBN(0x013ba727, 0x175a54ab), TOBN(0xca0cd190, 0xea5d8d10),
+ TOBN(0x85ea52c0, 0x95fd96a9), TOBN(0x2c591b9f, 0xbc5c3940)}},
+ {{TOBN(0x6fb4d4e4, 0x2bad4d5f), TOBN(0xfa4c3590, 0xfef0059b),
+ TOBN(0x6a10218a, 0xf5122294), TOBN(0x9a78a81a, 0xa85751d1)},
+ {TOBN(0x04f20579, 0xa98e84e7), TOBN(0xfe1242c0, 0x4997e5b5),
+ TOBN(0xe77a273b, 0xca21e1e4), TOBN(0xfcc8b1ef, 0x9411939d)}},
+ {{TOBN(0xe20ea302, 0x92d0487a), TOBN(0x1442dbec, 0x294b91fe),
+ TOBN(0x1f7a4afe, 0xbb6b0e8f), TOBN(0x1700ef74, 0x6889c318)},
+ {TOBN(0xf5bbffc3, 0x70f1fc62), TOBN(0x3b31d4b6, 0x69c79cca),
+ TOBN(0xe8bc2aab, 0xa7f6340d), TOBN(0xb0b08ab4, 0xa725e10a)}},
+ {{TOBN(0x44f05701, 0xae340050), TOBN(0xba4b3016, 0x1cf0c569),
+ TOBN(0x5aa29f83, 0xfbe19a51), TOBN(0x1b9ed428, 0xb71d752e)},
+ {TOBN(0x1666e54e, 0xeb4819f5), TOBN(0x616cdfed, 0x9e18b75b),
+ TOBN(0x112ed5be, 0x3ee27b0b), TOBN(0xfbf28319, 0x44c7de4d)}},
+ {{TOBN(0xd685ec85, 0xe0e60d84), TOBN(0x68037e30, 0x1db7ee78),
+ TOBN(0x5b65bdcd, 0x003c4d6e), TOBN(0x33e7363a, 0x93e29a6a)},
+ {TOBN(0x995b3a61, 0x08d0756c), TOBN(0xd727f85c, 0x2faf134b),
+ TOBN(0xfac6edf7, 0x1d337823), TOBN(0x99b9aa50, 0x0439b8b4)}},
+ {{TOBN(0x722eb104, 0xe2b4e075), TOBN(0x49987295, 0x437c4926),
+ TOBN(0xb1e4c0e4, 0x46a9b82d), TOBN(0xd0cb3197, 0x57a006f5)},
+ {TOBN(0xf3de0f7d, 0xd7808c56), TOBN(0xb5c54d8f, 0x51f89772),
+ TOBN(0x500a114a, 0xadbd31aa), TOBN(0x9afaaaa6, 0x295f6cab)}},
+ {{TOBN(0x94705e21, 0x04cf667a), TOBN(0xfc2a811b, 0x9d3935d7),
+ TOBN(0x560b0280, 0x6d09267c), TOBN(0xf19ed119, 0xf780e53b)},
+ {TOBN(0xf0227c09, 0x067b6269), TOBN(0x967b8533, 0x5caef599),
+ TOBN(0x155b9243, 0x68efeebc), TOBN(0xcd6d34f5, 0xc497bae6)}},
+ {{TOBN(0x1dd8d5d3, 0x6cceb370), TOBN(0x2aeac579, 0xa78d7bf9),
+ TOBN(0x5d65017d, 0x70b67a62), TOBN(0x70c8e44f, 0x17c53f67)},
+ {TOBN(0xd1fc0950, 0x86a34d09), TOBN(0xe0fca256, 0xe7134907),
+ TOBN(0xe24fa29c, 0x80fdd315), TOBN(0x2c4acd03, 0xd87499ad)}},
+ {{TOBN(0xbaaf7517, 0x3b5a9ba6), TOBN(0xb9cbe1f6, 0x12e51a51),
+ TOBN(0xd88edae3, 0x5e154897), TOBN(0xe4309c3c, 0x77b66ca0)},
+ {TOBN(0xf5555805, 0xf67f3746), TOBN(0x85fc37ba, 0xa36401ff),
+ TOBN(0xdf86e2ca, 0xd9499a53), TOBN(0x6270b2a3, 0xecbc955b)}},
+ {{TOBN(0xafae64f5, 0x974ad33b), TOBN(0x04d85977, 0xfe7b2df1),
+ TOBN(0x2a3db3ff, 0x4ab03f73), TOBN(0x0b87878a, 0x8702740a)},
+ {TOBN(0x6d263f01, 0x5a061732), TOBN(0xc25430ce, 0xa32a1901),
+ TOBN(0xf7ebab3d, 0xdb155018), TOBN(0x3a86f693, 0x63a9b78e)}},
+ {{TOBN(0x349ae368, 0xda9f3804), TOBN(0x470f07fe, 0xa164349c),
+ TOBN(0xd52f4cc9, 0x8562baa5), TOBN(0xc74a9e86, 0x2b290df3)},
+ {TOBN(0xd3a1aa35, 0x43471a24), TOBN(0x239446be, 0xb8194511),
+ TOBN(0xbec2dd00, 0x81dcd44d), TOBN(0xca3d7f0f, 0xc42ac82d)}},
+ {{TOBN(0x1f3db085, 0xfdaf4520), TOBN(0xbb6d3e80, 0x4549daf2),
+ TOBN(0xf5969d8a, 0x19ad5c42), TOBN(0x7052b13d, 0xdbfd1511)},
+ {TOBN(0x11890d1b, 0x682b9060), TOBN(0xa71d3883, 0xac34452c),
+ TOBN(0xa438055b, 0x783805b4), TOBN(0x43241277, 0x4725b23e)}},
+ {{TOBN(0xf20cf96e, 0x4901bbed), TOBN(0x6419c710, 0xf432a2bb),
+ TOBN(0x57a0fbb9, 0xdfa9cd7d), TOBN(0x589111e4, 0x00daa249)},
+ {TOBN(0x19809a33, 0x7b60554e), TOBN(0xea5f8887, 0xede283a4),
+ TOBN(0x2d713802, 0x503bfd35), TOBN(0x151bb0af, 0x585d2a53)}},
+ {{TOBN(0x40b08f74, 0x43b30ca8), TOBN(0xe10b5bba, 0xd9934583),
+ TOBN(0xe8a546d6, 0xb51110ad), TOBN(0x1dd50e66, 0x28e0b6c5)},
+ {TOBN(0x292e9d54, 0xcff2b821), TOBN(0x3882555d, 0x47281760),
+ TOBN(0x134838f8, 0x3724d6e3), TOBN(0xf2c679e0, 0x22ddcda1)}},
+ {{TOBN(0x40ee8815, 0x6d2a5768), TOBN(0x7f227bd2, 0x1c1e7e2d),
+ TOBN(0x487ba134, 0xd04ff443), TOBN(0x76e2ff3d, 0xc614e54b)},
+ {TOBN(0x36b88d6f, 0xa3177ec7), TOBN(0xbf731d51, 0x2328fff5),
+ TOBN(0x758caea2, 0x49ba158e), TOBN(0x5ab8ff4c, 0x02938188)}},
+ {{TOBN(0x33e16056, 0x35edc56d), TOBN(0x5a69d349, 0x7e940d79),
+ TOBN(0x6c4fd001, 0x03866dcb), TOBN(0x20a38f57, 0x4893cdef)},
+ {TOBN(0xfbf3e790, 0xfac3a15b), TOBN(0x6ed7ea2e, 0x7a4f8e6b),
+ TOBN(0xa663eb4f, 0xbc3aca86), TOBN(0x22061ea5, 0x080d53f7)}},
+ {{TOBN(0x2480dfe6, 0xf546783f), TOBN(0xd38bc6da, 0x5a0a641e),
+ TOBN(0xfb093cd1, 0x2ede8965), TOBN(0x89654db4, 0xacb455cf)},
+ {TOBN(0x413cbf9a, 0x26e1adee), TOBN(0x291f3764, 0x373294d4),
+ TOBN(0x00797257, 0x648083fe), TOBN(0x25f504d3, 0x208cc341)}},
+ {{TOBN(0x635a8e5e, 0xc3a0ee43), TOBN(0x70aaebca, 0x679898ff),
+ TOBN(0x9ee9f547, 0x5dc63d56), TOBN(0xce987966, 0xffb34d00)},
+ {TOBN(0xf9f86b19, 0x5e26310a), TOBN(0x9e435484, 0x382a8ca8),
+ TOBN(0x253bcb81, 0xc2352fe4), TOBN(0xa4eac8b0, 0x4474b571)}},
+ {{TOBN(0xc1b97512, 0xc1ad8cf8), TOBN(0x193b4e9e, 0x99e0b697),
+ TOBN(0x939d2716, 0x01e85df0), TOBN(0x4fb265b3, 0xcd44eafd)},
+ {TOBN(0x321e7dcd, 0xe51e1ae2), TOBN(0x8e3a8ca6, 0xe3d8b096),
+ TOBN(0x8de46cb0, 0x52604998), TOBN(0x91099ad8, 0x39072aa7)}},
+ {{TOBN(0x2617f91c, 0x93aa96b8), TOBN(0x0fc8716b, 0x7fca2e13),
+ TOBN(0xa7106f5e, 0x95328723), TOBN(0xd1c9c40b, 0x262e6522)},
+ {TOBN(0xb9bafe86, 0x42b7c094), TOBN(0x1873439d, 0x1543c021),
+ TOBN(0xe1baa5de, 0x5cbefd5d), TOBN(0xa363fc5e, 0x521e8aff)}},
+ {{TOBN(0xefe6320d, 0xf862eaac), TOBN(0x14419c63, 0x22c647dc),
+ TOBN(0x0e06707c, 0x4e46d428), TOBN(0xcb6c834f, 0x4a178f8f)},
+ {TOBN(0x0f993a45, 0xd30f917c), TOBN(0xd4c4b049, 0x9879afee),
+ TOBN(0xb6142a1e, 0x70500063), TOBN(0x7c9b41c3, 0xa5d9d605)}},
+ {{TOBN(0xbc00fc2f, 0x2f8ba2c7), TOBN(0x0966eb2f, 0x7c67aa28),
+ TOBN(0x13f7b516, 0x5a786972), TOBN(0x3bfb7557, 0x8a2fbba0)},
+ {TOBN(0x131c4f23, 0x5a2b9620), TOBN(0xbff3ed27, 0x6faf46be),
+ TOBN(0x9b4473d1, 0x7e172323), TOBN(0x421e8878, 0x339f6246)}},
+ {{TOBN(0x0fa8587a, 0x25a41632), TOBN(0xc0814124, 0xa35b6c93),
+ TOBN(0x2b18a9f5, 0x59ebb8db), TOBN(0x264e3357, 0x76edb29c)},
+ {TOBN(0xaf245ccd, 0xc87c51e2), TOBN(0x16b3015b, 0x501e6214),
+ TOBN(0xbb31c560, 0x0a3882ce), TOBN(0x6961bb94, 0xfec11e04)}},
+ {{TOBN(0x3b825b8d, 0xeff7a3a0), TOBN(0xbec33738, 0xb1df7326),
+ TOBN(0x68ad747c, 0x99604a1f), TOBN(0xd154c934, 0x9a3bd499)},
+ {TOBN(0xac33506f, 0x1cc7a906), TOBN(0x73bb5392, 0x6c560e8f),
+ TOBN(0x6428fcbe, 0x263e3944), TOBN(0xc11828d5, 0x1c387434)}},
+ {{TOBN(0x3cd04be1, 0x3e4b12ff), TOBN(0xc3aad9f9, 0x2d88667c),
+ TOBN(0xc52ddcf8, 0x248120cf), TOBN(0x985a892e, 0x2a389532)},
+ {TOBN(0xfbb4b21b, 0x3bb85fa0), TOBN(0xf95375e0, 0x8dfc6269),
+ TOBN(0xfb4fb06c, 0x7ee2acea), TOBN(0x6785426e, 0x309c4d1f)}},
+ {{TOBN(0x659b17c8, 0xd8ceb147), TOBN(0x9b649eee, 0xb70a5554),
+ TOBN(0x6b7fa0b5, 0xac6bc634), TOBN(0xd99fe2c7, 0x1d6e732f)},
+ {TOBN(0x30e6e762, 0x8d3abba2), TOBN(0x18fee6e7, 0xa797b799),
+ TOBN(0x5c9d360d, 0xc696464d), TOBN(0xe3baeb48, 0x27bfde12)}},
+ {{TOBN(0x2bf5db47, 0xf23206d5), TOBN(0x2f6d3420, 0x1d260152),
+ TOBN(0x17b87653, 0x3f8ff89a), TOBN(0x5157c30c, 0x378fa458)},
+ {TOBN(0x7517c5c5, 0x2d4fb936), TOBN(0xef22f7ac, 0xe6518cdc),
+ TOBN(0xdeb483e6, 0xbf847a64), TOBN(0xf5084558, 0x92e0fa89)}}},
+ {{{TOBN(0xab9659d8, 0xdf7304d4), TOBN(0xb71bcf1b, 0xff210e8e),
+ TOBN(0xa9a2438b, 0xd73fbd60), TOBN(0x4595cd1f, 0x5d11b4de)},
+ {TOBN(0x9c0d329a, 0x4835859d), TOBN(0x4a0f0d2d, 0x7dbb6e56),
+ TOBN(0xc6038e5e, 0xdf928a4e), TOBN(0xc9429621, 0x8f5ad154)}},
+ {{TOBN(0x91213462, 0xf23f2d92), TOBN(0x6cab71bd, 0x60b94078),
+ TOBN(0x6bdd0a63, 0x176cde20), TOBN(0x54c9b20c, 0xee4d54bc)},
+ {TOBN(0x3cd2d8aa, 0x9f2ac02f), TOBN(0x03f8e617, 0x206eedb0),
+ TOBN(0xc7f68e16, 0x93086434), TOBN(0x831469c5, 0x92dd3db9)}},
+ {{TOBN(0x8521df24, 0x8f981354), TOBN(0x587e23ec, 0x3588a259),
+ TOBN(0xcbedf281, 0xd7a0992c), TOBN(0x06930a55, 0x38961407)},
+ {TOBN(0x09320deb, 0xbe5bbe21), TOBN(0xa7ffa5b5, 0x2491817f),
+ TOBN(0xe6c8b4d9, 0x09065160), TOBN(0xac4f3992, 0xfff6d2a9)}},
+ {{TOBN(0x7aa7a158, 0x3ae9c1bd), TOBN(0xe0af6d98, 0xe37ce240),
+ TOBN(0xe54342d9, 0x28ab38b4), TOBN(0xe8b75007, 0x0a1c98ca)},
+ {TOBN(0xefce86af, 0xe02358f2), TOBN(0x31b8b856, 0xea921228),
+ TOBN(0x052a1912, 0x0a1c67fc), TOBN(0xb4069ea4, 0xe3aead59)}},
+ {{TOBN(0x3232d6e2, 0x7fa03cb3), TOBN(0xdb938e5b, 0x0fdd7d88),
+ TOBN(0x04c1d2cd, 0x2ccbfc5d), TOBN(0xd2f45c12, 0xaf3a580f)},
+ {TOBN(0x592620b5, 0x7883e614), TOBN(0x5fd27e68, 0xbe7c5f26),
+ TOBN(0x139e45a9, 0x1567e1e3), TOBN(0x2cc71d2d, 0x44d8aaaf)}},
+ {{TOBN(0x4a9090cd, 0xe36d0757), TOBN(0xf722d7b1, 0xd9a29382),
+ TOBN(0xfb7fb04c, 0x04b48ddf), TOBN(0x628ad2a7, 0xebe16f43)},
+ {TOBN(0xcd3fbfb5, 0x20226040), TOBN(0x6c34ecb1, 0x5104b6c4),
+ TOBN(0x30c0754e, 0xc903c188), TOBN(0xec336b08, 0x2d23cab0)}},
+ {{TOBN(0x473d62a2, 0x1e206ee5), TOBN(0xf1e27480, 0x8c49a633),
+ TOBN(0x87ab956c, 0xe9f6b2c3), TOBN(0x61830b48, 0x62b606ea)},
+ {TOBN(0x67cd6846, 0xe78e815f), TOBN(0xfe40139f, 0x4c02082a),
+ TOBN(0x52bbbfcb, 0x952ec365), TOBN(0x74c11642, 0x6b9836ab)}},
+ {{TOBN(0x9f51439e, 0x558df019), TOBN(0x230da4ba, 0xac712b27),
+ TOBN(0x518919e3, 0x55185a24), TOBN(0x4dcefcdd, 0x84b78f50)},
+ {TOBN(0xa7d90fb2, 0xa47d4c5a), TOBN(0x55ac9abf, 0xb30e009e),
+ TOBN(0xfd2fc359, 0x74eed273), TOBN(0xb72d824c, 0xdbea8faf)}},
+ {{TOBN(0xce721a74, 0x4513e2ca), TOBN(0x0b418612, 0x38240b2c),
+ TOBN(0x05199968, 0xd5baa450), TOBN(0xeb1757ed, 0x2b0e8c25)},
+ {TOBN(0x6ebc3e28, 0x3dfac6d5), TOBN(0xb2431e2e, 0x48a237f5),
+ TOBN(0x2acb5e23, 0x52f61499), TOBN(0x5558a2a7, 0xe06c936b)}},
+ {{TOBN(0xd213f923, 0xcbb13d1b), TOBN(0x98799f42, 0x5bfb9bfe),
+ TOBN(0x1ae8ddc9, 0x701144a9), TOBN(0x0b8b3bb6, 0x4c5595ee)},
+ {TOBN(0x0ea9ef2e, 0x3ecebb21), TOBN(0x17cb6c4b, 0x3671f9a7),
+ TOBN(0x47ef464f, 0x726f1d1f), TOBN(0x171b9484, 0x6943a276)}},
+ {{TOBN(0x51a4ae2d, 0x7ef0329c), TOBN(0x08509222, 0x91c4402a),
+ TOBN(0x64a61d35, 0xafd45bbc), TOBN(0x38f096fe, 0x3035a851)},
+ {TOBN(0xc7468b74, 0xa1dec027), TOBN(0xe8cf10e7, 0x4fc7dcba),
+ TOBN(0xea35ff40, 0xf4a06353), TOBN(0x0b4c0dfa, 0x8b77dd66)}},
+ {{TOBN(0x779b8552, 0xde7e5c19), TOBN(0xfab28609, 0xc1c0256c),
+ TOBN(0x64f58eee, 0xabd4743d), TOBN(0x4e8ef838, 0x7b6cc93b)},
+ {TOBN(0xee650d26, 0x4cb1bf3d), TOBN(0x4c1f9d09, 0x73dedf61),
+ TOBN(0xaef7c9d7, 0xbfb70ced), TOBN(0x1ec0507e, 0x1641de1e)}},
+ {{TOBN(0xcd7e5cc7, 0xcde45079), TOBN(0xde173c9a, 0x516ac9e4),
+ TOBN(0x517a8494, 0xc170315c), TOBN(0x438fd905, 0x91d8e8fb)},
+ {TOBN(0x5145c506, 0xc7d9630b), TOBN(0x6457a87b, 0xf47d4d75),
+ TOBN(0xd31646bf, 0x0d9a80e8), TOBN(0x453add2b, 0xcef3aabe)}},
+ {{TOBN(0xc9941109, 0xa607419d), TOBN(0xfaa71e62, 0xbb6bca80),
+ TOBN(0x34158c13, 0x07c431f3), TOBN(0x594abebc, 0x992bc47a)},
+ {TOBN(0x6dfea691, 0xeb78399f), TOBN(0x48aafb35, 0x3f42cba4),
+ TOBN(0xedcd65af, 0x077c04f0), TOBN(0x1a29a366, 0xe884491a)}},
+ {{TOBN(0x023a40e5, 0x1c21f2bf), TOBN(0xf99a513c, 0xa5057aee),
+ TOBN(0xa3fe7e25, 0xbcab072e), TOBN(0x8568d2e1, 0x40e32bcf)},
+ {TOBN(0x904594eb, 0xd3f69d9f), TOBN(0x181a9733, 0x07affab1),
+ TOBN(0xe4d68d76, 0xb6e330f4), TOBN(0x87a6dafb, 0xc75a7fc1)}},
+ {{TOBN(0x549db2b5, 0xef7d9289), TOBN(0x2480d4a8, 0x197f015a),
+ TOBN(0x61d5590b, 0xc40493b6), TOBN(0x3a55b52e, 0x6f780331)},
+ {TOBN(0x40eb8115, 0x309eadb0), TOBN(0xdea7de5a, 0x92e5c625),
+ TOBN(0x64d631f0, 0xcc6a3d5a), TOBN(0x9d5e9d7c, 0x93e8dd61)}},
+ {{TOBN(0xf297bef5, 0x206d3ffc), TOBN(0x23d5e033, 0x7d808bd4),
+ TOBN(0x4a4f6912, 0xd24cf5ba), TOBN(0xe4d8163b, 0x09cdaa8a)},
+ {TOBN(0x0e0de9ef, 0xd3082e8e), TOBN(0x4fe1246c, 0x0192f360),
+ TOBN(0x1f900150, 0x4b8eee0a), TOBN(0x5219da81, 0xf1da391b)}},
+ {{TOBN(0x7bf6a5c1, 0xf7ea25aa), TOBN(0xd165e6bf, 0xfbb07d5f),
+ TOBN(0xe3539361, 0x89e78671), TOBN(0xa3fcac89, 0x2bac4219)},
+ {TOBN(0xdfab6fd4, 0xf0baa8ab), TOBN(0x5a4adac1, 0xe2c1c2e5),
+ TOBN(0x6cd75e31, 0x40d85849), TOBN(0xce263fea, 0x19b39181)}},
+ {{TOBN(0xcb6803d3, 0x07032c72), TOBN(0x7f40d5ce, 0x790968c8),
+ TOBN(0xa6de86bd, 0xdce978f0), TOBN(0x25547c4f, 0x368f751c)},
+ {TOBN(0xb1e685fd, 0x65fb2a9e), TOBN(0xce69336f, 0x1eb9179c),
+ TOBN(0xb15d1c27, 0x12504442), TOBN(0xb7df465c, 0xb911a06b)}},
+ {{TOBN(0xb8d804a3, 0x315980cd), TOBN(0x693bc492, 0xfa3bebf7),
+ TOBN(0x3578aeee, 0x2253c504), TOBN(0x158de498, 0xcd2474a2)},
+ {TOBN(0x1331f5c7, 0xcfda8368), TOBN(0xd2d7bbb3, 0x78d7177e),
+ TOBN(0xdf61133a, 0xf3c1e46e), TOBN(0x5836ce7d, 0xd30e7be8)}},
+ {{TOBN(0x83084f19, 0x94f834cb), TOBN(0xd35653d4, 0x429ed782),
+ TOBN(0xa542f16f, 0x59e58243), TOBN(0xc2b52f65, 0x0470a22d)},
+ {TOBN(0xe3b6221b, 0x18f23d96), TOBN(0xcb05abac, 0x3f5252b4),
+ TOBN(0xca00938b, 0x87d61402), TOBN(0x2f186cdd, 0x411933e4)}},
+ {{TOBN(0xe042ece5, 0x9a29a5c5), TOBN(0xb19b3c07, 0x3b6c8402),
+ TOBN(0xc97667c7, 0x19d92684), TOBN(0xb5624622, 0xebc66372)},
+ {TOBN(0x0cb96e65, 0x3c04fa02), TOBN(0x83a7176c, 0x8eaa39aa),
+ TOBN(0x2033561d, 0xeaa1633f), TOBN(0x45a9d086, 0x4533df73)}},
+ {{TOBN(0xe0542c1d, 0x3dc090bc), TOBN(0x82c996ef, 0xaa59c167),
+ TOBN(0xe3f735e8, 0x0ee7fc4d), TOBN(0x7b179393, 0x7c35db79)},
+ {TOBN(0xb6419e25, 0xf8c5dbfd), TOBN(0x4d9d7a1e, 0x1f327b04),
+ TOBN(0x979f6f9b, 0x298dfca8), TOBN(0xc7c5dff1, 0x8de9366a)}},
+ {{TOBN(0x1b7a588d, 0x04c82bdd), TOBN(0x68005534, 0xf8319dfd),
+ TOBN(0xde8a55b5, 0xd8eb9580), TOBN(0x5ea886da, 0x8d5bca81)},
+ {TOBN(0xe8530a01, 0x252a0b4d), TOBN(0x1bffb4fe, 0x35eaa0a1),
+ TOBN(0x2ad828b1, 0xd8e99563), TOBN(0x7de96ef5, 0x95f9cd87)}},
+ {{TOBN(0x4abb2d0c, 0xd77d970c), TOBN(0x03cfb933, 0xd33ef9cb),
+ TOBN(0xb0547c01, 0x8b211fe9), TOBN(0x2fe64809, 0xa56ed1c6)},
+ {TOBN(0xcb7d5624, 0xc2ac98cc), TOBN(0x2a1372c0, 0x1a393e33),
+ TOBN(0xc8d1ec1c, 0x29660521), TOBN(0xf3d31b04, 0xb37ac3e9)}},
+ {{TOBN(0xa29ae9df, 0x5ece6e7c), TOBN(0x0603ac8f, 0x0facfb55),
+ TOBN(0xcfe85b7a, 0xdda233a5), TOBN(0xe618919f, 0xbd75f0b8)},
+ {TOBN(0xf555a3d2, 0x99bf1603), TOBN(0x1f43afc9, 0xf184255a),
+ TOBN(0xdcdaf341, 0x319a3e02), TOBN(0xd3b117ef, 0x03903a39)}},
+ {{TOBN(0xe095da13, 0x65d1d131), TOBN(0x86f16367, 0xc37ad03e),
+ TOBN(0x5f37389e, 0x462cd8dd), TOBN(0xc103fa04, 0xd67a60e6)},
+ {TOBN(0x57c34344, 0xf4b478f0), TOBN(0xce91edd8, 0xe117c98d),
+ TOBN(0x001777b0, 0x231fc12e), TOBN(0x11ae47f2, 0xb207bccb)}},
+ {{TOBN(0xd983cf8d, 0x20f8a242), TOBN(0x7aff5b1d, 0xf22e1ad8),
+ TOBN(0x68fd11d0, 0x7fc4feb3), TOBN(0x5d53ae90, 0xb0f1c3e1)},
+ {TOBN(0x50fb7905, 0xec041803), TOBN(0x85e3c977, 0x14404888),
+ TOBN(0x0e67faed, 0xac628d8f), TOBN(0x2e865150, 0x6668532c)}},
+ {{TOBN(0x15acaaa4, 0x6a67a6b0), TOBN(0xf4cdee25, 0xb25cec41),
+ TOBN(0x49ee565a, 0xe4c6701e), TOBN(0x2a04ca66, 0xfc7d63d8)},
+ {TOBN(0xeb105018, 0xef0543fb), TOBN(0xf709a4f5, 0xd1b0d81d),
+ TOBN(0x5b906ee6, 0x2915d333), TOBN(0xf4a87412, 0x96f1f0ab)}},
+ {{TOBN(0xb6b82fa7, 0x4d82f4c2), TOBN(0x90725a60, 0x6804efb3),
+ TOBN(0xbc82ec46, 0xadc3425e), TOBN(0xb7b80581, 0x2787843e)},
+ {TOBN(0xdf46d91c, 0xdd1fc74c), TOBN(0xdc1c62cb, 0xe783a6c4),
+ TOBN(0x59d1b9f3, 0x1a04cbba), TOBN(0xd87f6f72, 0x95e40764)}},
+ {{TOBN(0x02b4cfc1, 0x317f4a76), TOBN(0x8d2703eb, 0x91036bce),
+ TOBN(0x98206cc6, 0xa5e72a56), TOBN(0x57be9ed1, 0xcf53fb0f)},
+ {TOBN(0x09374571, 0xef0b17ac), TOBN(0x74b2655e, 0xd9181b38),
+ TOBN(0xc8f80ea8, 0x89935d0e), TOBN(0xc0d9e942, 0x91529936)}},
+ {{TOBN(0x19686041, 0x1e84e0e5), TOBN(0xa5db84d3, 0xaea34c93),
+ TOBN(0xf9d5bb19, 0x7073a732), TOBN(0xb8d2fe56, 0x6bcfd7c0)},
+ {TOBN(0x45775f36, 0xf3eb82fa), TOBN(0x8cb20ccc, 0xfdff8b58),
+ TOBN(0x1659b65f, 0x8374c110), TOBN(0xb8b4a422, 0x330c789a)}},
+ {{TOBN(0x75e3c3ea, 0x6fe8208b), TOBN(0xbd74b9e4, 0x286e78fe),
+ TOBN(0x0be2e81b, 0xd7d93a1a), TOBN(0x7ed06e27, 0xdd0a5aae)},
+ {TOBN(0x721f5a58, 0x6be8b800), TOBN(0x428299d1, 0xd846db28),
+ TOBN(0x95cb8e6b, 0x5be88ed3), TOBN(0xc3186b23, 0x1c034e11)}},
+ {{TOBN(0xa6312c9e, 0x8977d99b), TOBN(0xbe944331, 0x83f531e7),
+ TOBN(0x8232c0c2, 0x18d3b1d4), TOBN(0x617aae8b, 0xe1247b73)},
+ {TOBN(0x40153fc4, 0x282aec3b), TOBN(0xc6063d2f, 0xf7b8f823),
+ TOBN(0x68f10e58, 0x3304f94c), TOBN(0x31efae74, 0xee676346)}},
+ {{TOBN(0xbadb6c6d, 0x40a9b97c), TOBN(0x14702c63, 0x4f666256),
+ TOBN(0xdeb954f1, 0x5184b2e3), TOBN(0x5184a526, 0x94b6ca40)},
+ {TOBN(0xfff05337, 0x003c32ea), TOBN(0x5aa374dd, 0x205974c7),
+ TOBN(0x9a763854, 0x4b0dd71a), TOBN(0x459cd27f, 0xdeb947ec)}},
+ {{TOBN(0xa6e28161, 0x459c2b92), TOBN(0x2f020fa8, 0x75ee8ef5),
+ TOBN(0xb132ec2d, 0x30b06310), TOBN(0xc3e15899, 0xbc6a4530)},
+ {TOBN(0xdc5f53fe, 0xaa3f451a), TOBN(0x3a3c7f23, 0xc2d9acac),
+ TOBN(0x2ec2f892, 0x6b27e58b), TOBN(0x68466ee7, 0xd742799f)}},
+ {{TOBN(0x98324dd4, 0x1fa26613), TOBN(0xa2dc6dab, 0xbdc29d63),
+ TOBN(0xf9675faa, 0xd712d657), TOBN(0x813994be, 0x21fd8d15)},
+ {TOBN(0x5ccbb722, 0xfd4f7553), TOBN(0x5135ff8b, 0xf3a36b20),
+ TOBN(0x44be28af, 0x69559df5), TOBN(0x40b65bed, 0x9d41bf30)}},
+ {{TOBN(0xd98bf2a4, 0x3734e520), TOBN(0x5e3abbe3, 0x209bdcba),
+ TOBN(0x77c76553, 0xbc945b35), TOBN(0x5331c093, 0xc6ef14aa)},
+ {TOBN(0x518ffe29, 0x76b60c80), TOBN(0x2285593b, 0x7ace16f8),
+ TOBN(0xab1f64cc, 0xbe2b9784), TOBN(0xe8f2c0d9, 0xab2421b6)}},
+ {{TOBN(0x617d7174, 0xc1df065c), TOBN(0xafeeb5ab, 0x5f6578fa),
+ TOBN(0x16ff1329, 0x263b54a8), TOBN(0x45c55808, 0xc990dce3)},
+ {TOBN(0x42eab6c0, 0xecc8c177), TOBN(0x799ea9b5, 0x5982ecaa),
+ TOBN(0xf65da244, 0xb607ef8e), TOBN(0x8ab226ce, 0x32a3fc2c)}},
+ {{TOBN(0x745741e5, 0x7ea973dc), TOBN(0x5c00ca70, 0x20888f2e),
+ TOBN(0x7cdce3cf, 0x45fd9cf1), TOBN(0x8a741ef1, 0x5507f872)},
+ {TOBN(0x47c51c2f, 0x196b4cec), TOBN(0x70d08e43, 0xc97ea618),
+ TOBN(0x930da15c, 0x15b18a2b), TOBN(0x33b6c678, 0x2f610514)}},
+ {{TOBN(0xc662e4f8, 0x07ac9794), TOBN(0x1eccf050, 0xba06cb79),
+ TOBN(0x1ff08623, 0xe7d954e5), TOBN(0x6ef2c5fb, 0x24cf71c3)},
+ {TOBN(0xb2c063d2, 0x67978453), TOBN(0xa0cf3796, 0x1d654af8),
+ TOBN(0x7cb242ea, 0x7ebdaa37), TOBN(0x206e0b10, 0xb86747e0)}},
+ {{TOBN(0x481dae5f, 0xd5ecfefc), TOBN(0x07084fd8, 0xc2bff8fc),
+ TOBN(0x8040a01a, 0xea324596), TOBN(0x4c646980, 0xd4de4036)},
+ {TOBN(0x9eb8ab4e, 0xd65abfc3), TOBN(0xe01cb91f, 0x13541ec7),
+ TOBN(0x8f029adb, 0xfd695012), TOBN(0x9ae28483, 0x3c7569ec)}},
+ {{TOBN(0xa5614c9e, 0xa66d80a1), TOBN(0x680a3e44, 0x75f5f911),
+ TOBN(0x0c07b14d, 0xceba4fc1), TOBN(0x891c285b, 0xa13071c1)},
+ {TOBN(0xcac67ceb, 0x799ece3c), TOBN(0x29b910a9, 0x41e07e27),
+ TOBN(0x66bdb409, 0xf2e43123), TOBN(0x06f8b137, 0x7ac9ecbe)}},
+ {{TOBN(0x5981fafd, 0x38547090), TOBN(0x19ab8b9f, 0x85e3415d),
+ TOBN(0xfc28c194, 0xc7e31b27), TOBN(0x843be0aa, 0x6fbcbb42)},
+ {TOBN(0xf3b1ed43, 0xa6db836c), TOBN(0x2a1330e4, 0x01a45c05),
+ TOBN(0x4f19f3c5, 0x95c1a377), TOBN(0xa85f39d0, 0x44b5ee33)}},
+ {{TOBN(0x3da18e6d, 0x4ae52834), TOBN(0x5a403b39, 0x7423dcb0),
+ TOBN(0xbb555e0a, 0xf2374aef), TOBN(0x2ad599c4, 0x1e8ca111)},
+ {TOBN(0x1b3a2fb9, 0x014b3bf8), TOBN(0x73092684, 0xf66d5007),
+ TOBN(0x079f1426, 0xc4340102), TOBN(0x1827cf81, 0x8fddf4de)}},
+ {{TOBN(0xc83605f6, 0xf10ff927), TOBN(0xd3871451, 0x23739fc6),
+ TOBN(0x6d163450, 0xcac1c2cc), TOBN(0x6b521296, 0xa2ec1ac5)},
+ {TOBN(0x0606c4f9, 0x6e3cb4a5), TOBN(0xe47d3f41, 0x778abff7),
+ TOBN(0x425a8d5e, 0xbe8e3a45), TOBN(0x53ea9e97, 0xa6102160)}},
+ {{TOBN(0x477a106e, 0x39cbb688), TOBN(0x532401d2, 0xf3386d32),
+ TOBN(0x8e564f64, 0xb1b9b421), TOBN(0xca9b8388, 0x81dad33f)},
+ {TOBN(0xb1422b4e, 0x2093913e), TOBN(0x533d2f92, 0x69bc8112),
+ TOBN(0x3fa017be, 0xebe7b2c7), TOBN(0xb2767c4a, 0xcaf197c6)}},
+ {{TOBN(0xc925ff87, 0xaedbae9f), TOBN(0x7daf0eb9, 0x36880a54),
+ TOBN(0x9284ddf5, 0x9c4d0e71), TOBN(0x1581cf93, 0x316f8cf5)},
+ {TOBN(0x3eeca887, 0x3ac1f452), TOBN(0xb417fce9, 0xfb6aeffe),
+ TOBN(0xa5918046, 0xeefb8dc3), TOBN(0x73d318ac, 0x02209400)}},
+ {{TOBN(0xe800400f, 0x728693e5), TOBN(0xe87d814b, 0x339927ed),
+ TOBN(0x93e94d3b, 0x57ea9910), TOBN(0xff8a35b6, 0x2245fb69)},
+ {TOBN(0x043853d7, 0x7f200d34), TOBN(0x470f1e68, 0x0f653ce1),
+ TOBN(0x81ac05bd, 0x59a06379), TOBN(0xa14052c2, 0x03930c29)}},
+ {{TOBN(0x6b72fab5, 0x26bc2797), TOBN(0x13670d16, 0x99f16771),
+ TOBN(0x00170052, 0x1e3e48d1), TOBN(0x978fe401, 0xb7adf678)},
+ {TOBN(0x55ecfb92, 0xd41c5dd4), TOBN(0x5ff8e247, 0xc7b27da5),
+ TOBN(0xe7518272, 0x013fb606), TOBN(0x5768d7e5, 0x2f547a3c)}},
+ {{TOBN(0xbb24eaa3, 0x60017a5f), TOBN(0x6b18e6e4, 0x9c64ce9b),
+ TOBN(0xc225c655, 0x103dde07), TOBN(0xfc3672ae, 0x7592f7ea)},
+ {TOBN(0x9606ad77, 0xd06283a1), TOBN(0x542fc650, 0xe4d59d99),
+ TOBN(0xabb57c49, 0x2a40e7c2), TOBN(0xac948f13, 0xa8db9f55)}},
+ {{TOBN(0x6d4c9682, 0xb04465c3), TOBN(0xe3d062fa, 0x6468bd15),
+ TOBN(0xa51729ac, 0x5f318d7e), TOBN(0x1fc87df6, 0x9eb6fc95)},
+ {TOBN(0x63d146a8, 0x0591f652), TOBN(0xa861b8f7, 0x589621aa),
+ TOBN(0x59f5f15a, 0xce31348c), TOBN(0x8f663391, 0x440da6da)}},
+ {{TOBN(0xcfa778ac, 0xb591ffa3), TOBN(0x027ca9c5, 0x4cdfebce),
+ TOBN(0xbe8e05a5, 0x444ea6b3), TOBN(0x8aab4e69, 0xa78d8254)},
+ {TOBN(0x2437f04f, 0xb474d6b8), TOBN(0x6597ffd4, 0x045b3855),
+ TOBN(0xbb0aea4e, 0xca47ecaa), TOBN(0x568aae83, 0x85c7ebfc)}},
+ {{TOBN(0x0e966e64, 0xc73b2383), TOBN(0x49eb3447, 0xd17d8762),
+ TOBN(0xde107821, 0x8da05dab), TOBN(0x443d8baa, 0x016b7236)},
+ {TOBN(0x163b63a5, 0xea7610d6), TOBN(0xe47e4185, 0xce1ca979),
+ TOBN(0xae648b65, 0x80baa132), TOBN(0xebf53de2, 0x0e0d5b64)}},
+ {{TOBN(0x8d3bfcb4, 0xd3c8c1ca), TOBN(0x0d914ef3, 0x5d04b309),
+ TOBN(0x55ef6415, 0x3de7d395), TOBN(0xbde1666f, 0x26b850e8)},
+ {TOBN(0xdbe1ca6e, 0xd449ab19), TOBN(0x8902b322, 0xe89a2672),
+ TOBN(0xb1674b7e, 0xdacb7a53), TOBN(0x8e9faf6e, 0xf52523ff)}},
+ {{TOBN(0x6ba535da, 0x9a85788b), TOBN(0xd21f03ae, 0xbd0626d4),
+ TOBN(0x099f8c47, 0xe873dc64), TOBN(0xcda8564d, 0x018ec97e)},
+ {TOBN(0x3e8d7a5c, 0xde92c68c), TOBN(0x78e035a1, 0x73323cc4),
+ TOBN(0x3ef26275, 0xf880ff7c), TOBN(0xa4ee3dff, 0x273eedaa)}},
+ {{TOBN(0x58823507, 0xaf4e18f8), TOBN(0x967ec9b5, 0x0672f328),
+ TOBN(0x9ded19d9, 0x559d3186), TOBN(0x5e2ab3de, 0x6cdce39c)},
+ {TOBN(0xabad6e4d, 0x11c226df), TOBN(0xf9783f43, 0x87723014),
+ TOBN(0x9a49a0cf, 0x1a885719), TOBN(0xfc0c1a5a, 0x90da9dbf)}},
+ {{TOBN(0x8bbaec49, 0x571d92ac), TOBN(0x569e85fe, 0x4692517f),
+ TOBN(0x8333b014, 0xa14ea4af), TOBN(0x32f2a62f, 0x12e5c5ad)},
+ {TOBN(0x98c2ce3a, 0x06d89b85), TOBN(0xb90741aa, 0x2ff77a08),
+ TOBN(0x2530defc, 0x01f795a2), TOBN(0xd6e5ba0b, 0x84b3c199)}},
+ {{TOBN(0x7d8e8451, 0x12e4c936), TOBN(0xae419f7d, 0xbd0be17b),
+ TOBN(0xa583fc8c, 0x22262bc9), TOBN(0x6b842ac7, 0x91bfe2bd)},
+ {TOBN(0x33cef4e9, 0x440d6827), TOBN(0x5f69f4de, 0xef81fb14),
+ TOBN(0xf16cf6f6, 0x234fbb92), TOBN(0x76ae3fc3, 0xd9e7e158)}},
+ {{TOBN(0x4e89f6c2, 0xe9740b33), TOBN(0x677bc85d, 0x4962d6a1),
+ TOBN(0x6c6d8a7f, 0x68d10d15), TOBN(0x5f9a7224, 0x0257b1cd)},
+ {TOBN(0x7096b916, 0x4ad85961), TOBN(0x5f8c47f7, 0xe657ab4a),
+ TOBN(0xde57d7d0, 0xf7461d7e), TOBN(0x7eb6094d, 0x80ce5ee2)}},
+ {{TOBN(0x0b1e1dfd, 0x34190547), TOBN(0x8a394f43, 0xf05dd150),
+ TOBN(0x0a9eb24d, 0x97df44e6), TOBN(0x78ca06bf, 0x87675719)},
+ {TOBN(0x6f0b3462, 0x6ffeec22), TOBN(0x9d91bcea, 0x36cdd8fb),
+ TOBN(0xac83363c, 0xa105be47), TOBN(0x81ba76c1, 0x069710e3)}},
+ {{TOBN(0x3d1b24cb, 0x28c682c6), TOBN(0x27f25228, 0x8612575b),
+ TOBN(0xb587c779, 0xe8e66e98), TOBN(0x7b0c03e9, 0x405eb1fe)},
+ {TOBN(0xfdf0d030, 0x15b548e7), TOBN(0xa8be76e0, 0x38b36af7),
+ TOBN(0x4cdab04a, 0x4f310c40), TOBN(0x6287223e, 0xf47ecaec)}},
+ {{TOBN(0x678e6055, 0x8b399320), TOBN(0x61fe3fa6, 0xc01e4646),
+ TOBN(0xc482866b, 0x03261a5e), TOBN(0xdfcf45b8, 0x5c2f244a)},
+ {TOBN(0x8fab9a51, 0x2f684b43), TOBN(0xf796c654, 0xc7220a66),
+ TOBN(0x1d90707e, 0xf5afa58f), TOBN(0x2c421d97, 0x4fdbe0de)}},
+ {{TOBN(0xc4f4cda3, 0xaf2ebc2f), TOBN(0xa0af843d, 0xcb4efe24),
+ TOBN(0x53b857c1, 0x9ccd10b1), TOBN(0xddc9d1eb, 0x914d3e04)},
+ {TOBN(0x7bdec8bb, 0x62771deb), TOBN(0x829277aa, 0x91c5aa81),
+ TOBN(0x7af18dd6, 0x832391ae), TOBN(0x1740f316, 0xc71a84ca)}}},
+ {{{TOBN(0x8928e99a, 0xeeaf8c49), TOBN(0xee7aa73d, 0x6e24d728),
+ TOBN(0x4c5007c2, 0xe72b156c), TOBN(0x5fcf57c5, 0xed408a1d)},
+ {TOBN(0x9f719e39, 0xb6057604), TOBN(0x7d343c01, 0xc2868bbf),
+ TOBN(0x2cca254b, 0x7e103e2d), TOBN(0xe6eb38a9, 0xf131bea2)}},
+ {{TOBN(0xb33e624f, 0x8be762b4), TOBN(0x2a9ee4d1, 0x058e3413),
+ TOBN(0x968e6369, 0x67d805fa), TOBN(0x9848949b, 0x7db8bfd7)},
+ {TOBN(0x5308d7e5, 0xd23a8417), TOBN(0x892f3b1d, 0xf3e29da5),
+ TOBN(0xc95c139e, 0x3dee471f), TOBN(0x8631594d, 0xd757e089)}},
+ {{TOBN(0xe0c82a3c, 0xde918dcc), TOBN(0x2e7b5994, 0x26fdcf4b),
+ TOBN(0x82c50249, 0x32cb1b2d), TOBN(0xea613a9d, 0x7657ae07)},
+ {TOBN(0xc2eb5f6c, 0xf1fdc9f7), TOBN(0xb6eae8b8, 0x879fe682),
+ TOBN(0x253dfee0, 0x591cbc7f), TOBN(0x000da713, 0x3e1290e6)}},
+ {{TOBN(0x1083e2ea, 0x1f095615), TOBN(0x0a28ad77, 0x14e68c33),
+ TOBN(0x6bfc0252, 0x3d8818be), TOBN(0xb585113a, 0xf35850cd)},
+ {TOBN(0x7d935f0b, 0x30df8aa1), TOBN(0xaddda07c, 0x4ab7e3ac),
+ TOBN(0x92c34299, 0x552f00cb), TOBN(0xc33ed1de, 0x2909df6c)}},
+ {{TOBN(0x22c2195d, 0x80e87766), TOBN(0x9e99e6d8, 0x9ddf4ac0),
+ TOBN(0x09642e4e, 0x65e74934), TOBN(0x2610ffa2, 0xff1ff241)},
+ {TOBN(0x4d1d47d4, 0x751c8159), TOBN(0x697b4985, 0xaf3a9363),
+ TOBN(0x0318ca46, 0x87477c33), TOBN(0xa90cb565, 0x9441eff3)}},
+ {{TOBN(0x58bb3848, 0x36f024cb), TOBN(0x85be1f77, 0x36016168),
+ TOBN(0x6c59587c, 0xdc7e07f1), TOBN(0x191be071, 0xaf1d8f02)},
+ {TOBN(0xbf169fa5, 0xcca5e55c), TOBN(0x3864ba3c, 0xf7d04eac),
+ TOBN(0x915e367f, 0x8d7d05db), TOBN(0xb48a876d, 0xa6549e5d)}},
+ {{TOBN(0xef89c656, 0x580e40a2), TOBN(0xf194ed8c, 0x728068bc),
+ TOBN(0x74528045, 0xa47990c9), TOBN(0xf53fc7d7, 0x5e1a4649)},
+ {TOBN(0xbec5ae9b, 0x78593e7d), TOBN(0x2cac4ee3, 0x41db65d7),
+ TOBN(0xa8c1eb24, 0x04a3d39b), TOBN(0x53b7d634, 0x03f8f3ef)}},
+ {{TOBN(0x2dc40d48, 0x3e07113c), TOBN(0x6e4a5d39, 0x7d8b63ae),
+ TOBN(0x5582a94b, 0x79684c2b), TOBN(0x932b33d4, 0x622da26c)},
+ {TOBN(0xf534f651, 0x0dbbf08d), TOBN(0x211d07c9, 0x64c23a52),
+ TOBN(0x0eeece0f, 0xee5bdc9b), TOBN(0xdf178168, 0xf7015558)}},
+ {{TOBN(0xd4294635, 0x0a712229), TOBN(0x93cbe448, 0x09273f8c),
+ TOBN(0x00b095ef, 0x8f13bc83), TOBN(0xbb741972, 0x8798978c)},
+ {TOBN(0x9d7309a2, 0x56dbe6e7), TOBN(0xe578ec56, 0x5a5d39ec),
+ TOBN(0x3961151b, 0x851f9a31), TOBN(0x2da7715d, 0xe5709eb4)}},
+ {{TOBN(0x867f3017, 0x53dfabf0), TOBN(0x728d2078, 0xb8e39259),
+ TOBN(0x5c75a0cd, 0x815d9958), TOBN(0xf84867a6, 0x16603be1)},
+ {TOBN(0xc865b13d, 0x70e35b1c), TOBN(0x02414468, 0x19b03e2c),
+ TOBN(0xe46041da, 0xac1f3121), TOBN(0x7c9017ad, 0x6f028a7c)}},
+ {{TOBN(0xabc96de9, 0x0a482873), TOBN(0x4265d6b1, 0xb77e54d4),
+ TOBN(0x68c38e79, 0xa57d88e7), TOBN(0xd461d766, 0x9ce82de3)},
+ {TOBN(0x817a9ec5, 0x64a7e489), TOBN(0xcc5675cd, 0xa0def5f2),
+ TOBN(0x9a00e785, 0x985d494e), TOBN(0xc626833f, 0x1b03514a)}},
+ {{TOBN(0xabe7905a, 0x83cdd60e), TOBN(0x50602fb5, 0xa1170184),
+ TOBN(0x689886cd, 0xb023642a), TOBN(0xd568d090, 0xa6e1fb00)},
+ {TOBN(0x5b1922c7, 0x0259217f), TOBN(0x93831cd9, 0xc43141e4),
+ TOBN(0xdfca3587, 0x0c95f86e), TOBN(0xdec2057a, 0x568ae828)}},
+ {{TOBN(0xc44ea599, 0xf98a759a), TOBN(0x55a0a7a2, 0xf7c23c1d),
+ TOBN(0xd5ffb6e6, 0x94c4f687), TOBN(0x3563cce2, 0x12848478)},
+ {TOBN(0x812b3517, 0xe7b1fbe1), TOBN(0x8a7dc979, 0x4f7338e0),
+ TOBN(0x211ecee9, 0x52d048db), TOBN(0x2eea4056, 0xc86ea3b8)}},
+ {{TOBN(0xd8cb68a7, 0xba772b34), TOBN(0xe16ed341, 0x5f4e2541),
+ TOBN(0x9b32f6a6, 0x0fec14db), TOBN(0xeee376f7, 0x391698be)},
+ {TOBN(0xe9a7aa17, 0x83674c02), TOBN(0x65832f97, 0x5843022a),
+ TOBN(0x29f3a8da, 0x5ba4990f), TOBN(0x79a59c3a, 0xfb8e3216)}},
+ {{TOBN(0x9cdc4d2e, 0xbd19bb16), TOBN(0xc6c7cfd0, 0xb3262d86),
+ TOBN(0xd4ce14d0, 0x969c0b47), TOBN(0x1fa352b7, 0x13e56128)},
+ {TOBN(0x383d55b8, 0x973db6d3), TOBN(0x71836850, 0xe8e5b7bf),
+ TOBN(0xc7714596, 0xe6bb571f), TOBN(0x259df31f, 0x2d5b2dd2)}},
+ {{TOBN(0x568f8925, 0x913cc16d), TOBN(0x18bc5b6d, 0xe1a26f5a),
+ TOBN(0xdfa413be, 0xf5f499ae), TOBN(0xf8835dec, 0xc3f0ae84)},
+ {TOBN(0xb6e60bd8, 0x65a40ab0), TOBN(0x65596439, 0x194b377e),
+ TOBN(0xbcd85625, 0x92084a69), TOBN(0x5ce433b9, 0x4f23ede0)}},
+ {{TOBN(0xe8e8f04f, 0x6ad65143), TOBN(0x11511827, 0xd6e14af6),
+ TOBN(0x3d390a10, 0x8295c0c7), TOBN(0x71e29ee4, 0x621eba16)},
+ {TOBN(0xa588fc09, 0x63717b46), TOBN(0x02be02fe, 0xe06ad4a2),
+ TOBN(0x931558c6, 0x04c22b22), TOBN(0xbb4d4bd6, 0x12f3c849)}},
+ {{TOBN(0x54a4f496, 0x20efd662), TOBN(0x92ba6d20, 0xc5952d14),
+ TOBN(0x2db8ea1e, 0xcc9784c2), TOBN(0x81cc10ca, 0x4b353644)},
+ {TOBN(0x40b570ad, 0x4b4d7f6c), TOBN(0x5c9f1d96, 0x84a1dcd2),
+ TOBN(0x01379f81, 0x3147e797), TOBN(0xe5c6097b, 0x2bd499f5)}},
+ {{TOBN(0x40dcafa6, 0x328e5e20), TOBN(0xf7b5244a, 0x54815550),
+ TOBN(0xb9a4f118, 0x47bfc978), TOBN(0x0ea0e79f, 0xd25825b1)},
+ {TOBN(0xa50f96eb, 0x646c7ecf), TOBN(0xeb811493, 0x446dea9d),
+ TOBN(0x2af04677, 0xdfabcf69), TOBN(0xbe3a068f, 0xc713f6e8)}},
+ {{TOBN(0x860d523d, 0x42e06189), TOBN(0xbf077941, 0x4e3aff13),
+ TOBN(0x0b616dca, 0xc1b20650), TOBN(0xe66dd6d1, 0x2131300d)},
+ {TOBN(0xd4a0fd67, 0xff99abde), TOBN(0xc9903550, 0xc7aac50d),
+ TOBN(0x022ecf8b, 0x7c46b2d7), TOBN(0x3333b1e8, 0x3abf92af)}},
+ {{TOBN(0x11cc113c, 0x6c491c14), TOBN(0x05976688, 0x80dd3f88),
+ TOBN(0xf5b4d9e7, 0x29d932ed), TOBN(0xe982aad8, 0xa2c38b6d)},
+ {TOBN(0x6f925347, 0x8be0dcf0), TOBN(0x700080ae, 0x65ca53f2),
+ TOBN(0xd8131156, 0x443ca77f), TOBN(0xe92d6942, 0xec51f984)}},
+ {{TOBN(0xd2a08af8, 0x85dfe9ae), TOBN(0xd825d9a5, 0x4d2a86ca),
+ TOBN(0x2c53988d, 0x39dff020), TOBN(0xf38b135a, 0x430cdc40)},
+ {TOBN(0x0c918ae0, 0x62a7150b), TOBN(0xf31fd8de, 0x0c340e9b),
+ TOBN(0xafa0e7ae, 0x4dbbf02e), TOBN(0x5847fb2a, 0x5eba6239)}},
+ {{TOBN(0x6b1647dc, 0xdccbac8b), TOBN(0xb642aa78, 0x06f485c8),
+ TOBN(0x873f3765, 0x7038ecdf), TOBN(0x2ce5e865, 0xfa49d3fe)},
+ {TOBN(0xea223788, 0xc98c4400), TOBN(0x8104a8cd, 0xf1fa5279),
+ TOBN(0xbcf7cc7a, 0x06becfd7), TOBN(0x49424316, 0xc8f974ae)}},
+ {{TOBN(0xc0da65e7, 0x84d6365d), TOBN(0xbcb7443f, 0x8f759fb8),
+ TOBN(0x35c712b1, 0x7ae81930), TOBN(0x80428dff, 0x4c6e08ab)},
+ {TOBN(0xf19dafef, 0xa4faf843), TOBN(0xced8538d, 0xffa9855f),
+ TOBN(0x20ac409c, 0xbe3ac7ce), TOBN(0x358c1fb6, 0x882da71e)}},
+ {{TOBN(0xafa9c0e5, 0xfd349961), TOBN(0x2b2cfa51, 0x8421c2fc),
+ TOBN(0x2a80db17, 0xf3a28d38), TOBN(0xa8aba539, 0x5d138e7e)},
+ {TOBN(0x52012d1d, 0x6e96eb8d), TOBN(0x65d8dea0, 0xcbaf9622),
+ TOBN(0x57735447, 0xb264f56c), TOBN(0xbeebef3f, 0x1b6c8da2)}},
+ {{TOBN(0xfc346d98, 0xce785254), TOBN(0xd50e8d72, 0xbb64a161),
+ TOBN(0xc03567c7, 0x49794add), TOBN(0x15a76065, 0x752c7ef6)},
+ {TOBN(0x59f3a222, 0x961f23d6), TOBN(0x378e4438, 0x73ecc0b0),
+ TOBN(0xc74be434, 0x5a82fde4), TOBN(0xae509af2, 0xd8b9cf34)}},
+ {{TOBN(0x4a61ee46, 0x577f44a1), TOBN(0xe09b748c, 0xb611deeb),
+ TOBN(0xc0481b2c, 0xf5f7b884), TOBN(0x35626678, 0x61acfa6b)},
+ {TOBN(0x37f4c518, 0xbf8d21e6), TOBN(0x22d96531, 0xb205a76d),
+ TOBN(0x37fb85e1, 0x954073c0), TOBN(0xbceafe4f, 0x65b3a567)}},
+ {{TOBN(0xefecdef7, 0xbe42a582), TOBN(0xd3fc6080, 0x65046be6),
+ TOBN(0xc9af13c8, 0x09e8dba9), TOBN(0x1e6c9847, 0x641491ff)},
+ {TOBN(0x3b574925, 0xd30c31f7), TOBN(0xb7eb72ba, 0xac2a2122),
+ TOBN(0x776a0dac, 0xef0859e7), TOBN(0x06fec314, 0x21900942)}},
+ {{TOBN(0x2464bc10, 0xf8c22049), TOBN(0x9bfbcce7, 0x875ebf69),
+ TOBN(0xd7a88e2a, 0x4336326b), TOBN(0xda05261c, 0x5bc2acfa)},
+ {TOBN(0xc29f5bdc, 0xeba7efc8), TOBN(0x471237ca, 0x25dbbf2e),
+ TOBN(0xa72773f2, 0x2975f127), TOBN(0xdc744e8e, 0x04d0b326)}},
+ {{TOBN(0x38a7ed16, 0xa56edb73), TOBN(0x64357e37, 0x2c007e70),
+ TOBN(0xa167d15b, 0x5080b400), TOBN(0x07b41164, 0x23de4be1)},
+ {TOBN(0xb2d91e32, 0x74c89883), TOBN(0x3c162821, 0x2882e7ed),
+ TOBN(0xad6b36ba, 0x7503e482), TOBN(0x48434e8e, 0x0ea34331)}},
+ {{TOBN(0x79f4f24f, 0x2c7ae0b9), TOBN(0xc46fbf81, 0x1939b44a),
+ TOBN(0x76fefae8, 0x56595eb1), TOBN(0x417b66ab, 0xcd5f29c7)},
+ {TOBN(0x5f2332b2, 0xc5ceec20), TOBN(0xd69661ff, 0xe1a1cae2),
+ TOBN(0x5ede7e52, 0x9b0286e6), TOBN(0x9d062529, 0xe276b993)}},
+ {{TOBN(0x324794b0, 0x7e50122b), TOBN(0xdd744f8b, 0x4af07ca5),
+ TOBN(0x30a12f08, 0xd63fc97b), TOBN(0x39650f1a, 0x76626d9d)},
+ {TOBN(0x101b47f7, 0x1fa38477), TOBN(0x3d815f19, 0xd4dc124f),
+ TOBN(0x1569ae95, 0xb26eb58a), TOBN(0xc3cde188, 0x95fb1887)}},
+ {{TOBN(0x54e9f37b, 0xf9539a48), TOBN(0xb0100e06, 0x7408c1a5),
+ TOBN(0x821d9811, 0xea580cbb), TOBN(0x8af52d35, 0x86e50c56)},
+ {TOBN(0xdfbd9d47, 0xdbbf698b), TOBN(0x2961a1ea, 0x03dc1c73),
+ TOBN(0x203d38f8, 0xe76a5df8), TOBN(0x08a53a68, 0x6def707a)}},
+ {{TOBN(0x26eefb48, 0x1bee45d4), TOBN(0xb3cee346, 0x3c688036),
+ TOBN(0x463c5315, 0xc42f2469), TOBN(0x19d84d2e, 0x81378162)},
+ {TOBN(0x22d7c3c5, 0x1c4d349f), TOBN(0x65965844, 0x163d59c5),
+ TOBN(0xcf198c56, 0xb8abceae), TOBN(0x6fb1fb1b, 0x628559d5)}},
+ {{TOBN(0x8bbffd06, 0x07bf8fe3), TOBN(0x46259c58, 0x3467734b),
+ TOBN(0xd8953cea, 0x35f7f0d3), TOBN(0x1f0bece2, 0xd65b0ff1)},
+ {TOBN(0xf7d5b4b3, 0xf3c72914), TOBN(0x29e8ea95, 0x3cb53389),
+ TOBN(0x4a365626, 0x836b6d46), TOBN(0xe849f910, 0xea174fde)}},
+ {{TOBN(0x7ec62fbb, 0xf4737f21), TOBN(0xd8dba5ab, 0x6209f5ac),
+ TOBN(0x24b5d7a9, 0xa5f9adbe), TOBN(0x707d28f7, 0xa61dc768)},
+ {TOBN(0x7711460b, 0xcaa999ea), TOBN(0xba7b174d, 0x1c92e4cc),
+ TOBN(0x3c4bab66, 0x18d4bf2d), TOBN(0xb8f0c980, 0xeb8bd279)}},
+ {{TOBN(0x024bea9a, 0x324b4737), TOBN(0xfba9e423, 0x32a83bca),
+ TOBN(0x6e635643, 0xa232dced), TOBN(0x99619367, 0x2571c8ba)},
+ {TOBN(0xe8c9f357, 0x54b7032b), TOBN(0xf936b3ba, 0x2442d54a),
+ TOBN(0x2263f0f0, 0x8290c65a), TOBN(0x48989780, 0xee2c7fdb)}},
+ {{TOBN(0xadc5d55a, 0x13d4f95e), TOBN(0x737cff85, 0xad9b8500),
+ TOBN(0x271c557b, 0x8a73f43d), TOBN(0xbed617a4, 0xe18bc476)},
+ {TOBN(0x66245401, 0x7dfd8ab2), TOBN(0xae7b89ae, 0x3a2870aa),
+ TOBN(0x1b555f53, 0x23a7e545), TOBN(0x6791e247, 0xbe057e4c)}},
+ {{TOBN(0x860136ad, 0x324fa34d), TOBN(0xea111447, 0x4cbeae28),
+ TOBN(0x023a4270, 0xbedd3299), TOBN(0x3d5c3a7f, 0xc1c35c34)},
+ {TOBN(0xb0f6db67, 0x8d0412d2), TOBN(0xd92625e2, 0xfcdc6b9a),
+ TOBN(0x92ae5ccc, 0x4e28a982), TOBN(0xea251c36, 0x47a3ce7e)}},
+ {{TOBN(0x9d658932, 0x790691bf), TOBN(0xed610589, 0x06b736ae),
+ TOBN(0x712c2f04, 0xc0d63b6e), TOBN(0x5cf06fd5, 0xc63d488f)},
+ {TOBN(0x97363fac, 0xd9588e41), TOBN(0x1f9bf762, 0x2b93257e),
+ TOBN(0xa9d1ffc4, 0x667acace), TOBN(0x1cf4a1aa, 0x0a061ecf)}},
+ {{TOBN(0x40e48a49, 0xdc1818d0), TOBN(0x0643ff39, 0xa3621ab0),
+ TOBN(0x5768640c, 0xe39ef639), TOBN(0x1fc099ea, 0x04d86854)},
+ {TOBN(0x9130b9c3, 0xeccd28fd), TOBN(0xd743cbd2, 0x7eec54ab),
+ TOBN(0x052b146f, 0xe5b475b6), TOBN(0x058d9a82, 0x900a7d1f)}},
+ {{TOBN(0x65e02292, 0x91262b72), TOBN(0x96f924f9, 0xbb0edf03),
+ TOBN(0x5cfa59c8, 0xfe206842), TOBN(0xf6037004, 0x5eafa720)},
+ {TOBN(0x5f30699e, 0x18d7dd96), TOBN(0x381e8782, 0xcbab2495),
+ TOBN(0x91669b46, 0xdd8be949), TOBN(0xb40606f5, 0x26aae8ef)}},
+ {{TOBN(0x2812b839, 0xfc6751a4), TOBN(0x16196214, 0xfba800ef),
+ TOBN(0x4398d5ca, 0x4c1a2875), TOBN(0x720c00ee, 0x653d8349)},
+ {TOBN(0xc2699eb0, 0xd820007c), TOBN(0x880ee660, 0xa39b5825),
+ TOBN(0x70694694, 0x471f6984), TOBN(0xf7d16ea8, 0xe3dda99a)}},
+ {{TOBN(0x28d675b2, 0xc0519a23), TOBN(0x9ebf94fe, 0x4f6952e3),
+ TOBN(0xf28bb767, 0xa2294a8a), TOBN(0x85512b4d, 0xfe0af3f5)},
+ {TOBN(0x18958ba8, 0x99b16a0d), TOBN(0x95c2430c, 0xba7548a7),
+ TOBN(0xb30d1b10, 0xa16be615), TOBN(0xe3ebbb97, 0x85bfb74c)}},
+ {{TOBN(0xa3273cfe, 0x18549fdb), TOBN(0xf6e200bf, 0x4fcdb792),
+ TOBN(0x54a76e18, 0x83aba56c), TOBN(0x73ec66f6, 0x89ef6aa2)},
+ {TOBN(0x8d17add7, 0xd1b9a305), TOBN(0xa959c5b9, 0xb7ae1b9d),
+ TOBN(0x88643522, 0x6bcc094a), TOBN(0xcc5616c4, 0xd7d429b9)}},
+ {{TOBN(0xa6dada01, 0xe6a33f7c), TOBN(0xc6217a07, 0x9d4e70ad),
+ TOBN(0xd619a818, 0x09c15b7c), TOBN(0xea06b329, 0x0e80c854)},
+ {TOBN(0x174811ce, 0xa5f5e7b9), TOBN(0x66dfc310, 0x787c65f4),
+ TOBN(0x4ea7bd69, 0x3316ab54), TOBN(0xc12c4acb, 0x1dcc0f70)}},
+ {{TOBN(0xe4308d1a, 0x1e407dd9), TOBN(0xe8a3587c, 0x91afa997),
+ TOBN(0xea296c12, 0xab77b7a5), TOBN(0xb5ad49e4, 0x673c0d52)},
+ {TOBN(0x40f9b2b2, 0x7006085a), TOBN(0xa88ff340, 0x87bf6ec2),
+ TOBN(0x978603b1, 0x4e3066a6), TOBN(0xb3f99fc2, 0xb5e486e2)}},
+ {{TOBN(0x07b53f5e, 0xb2e63645), TOBN(0xbe57e547, 0x84c84232),
+ TOBN(0xd779c216, 0x7214d5cf), TOBN(0x617969cd, 0x029a3aca)},
+ {TOBN(0xd17668cd, 0x8a7017a0), TOBN(0x77b4d19a, 0xbe9b7ee8),
+ TOBN(0x58fd0e93, 0x9c161776), TOBN(0xa8c4f4ef, 0xd5968a72)}},
+ {{TOBN(0x296071cc, 0x67b3de77), TOBN(0xae3c0b8e, 0x634f7905),
+ TOBN(0x67e440c2, 0x8a7100c9), TOBN(0xbb8c3c1b, 0xeb4b9b42)},
+ {TOBN(0x6d71e8ea, 0xc51b3583), TOBN(0x7591f5af, 0x9525e642),
+ TOBN(0xf73a2f7b, 0x13f509f3), TOBN(0x618487aa, 0x5619ac9b)}},
+ {{TOBN(0x3a72e5f7, 0x9d61718a), TOBN(0x00413bcc, 0x7592d28c),
+ TOBN(0x7d9b11d3, 0x963c35cf), TOBN(0x77623bcf, 0xb90a46ed)},
+ {TOBN(0xdeef273b, 0xdcdd2a50), TOBN(0x4a741f9b, 0x0601846e),
+ TOBN(0x33b89e51, 0x0ec6e929), TOBN(0xcb02319f, 0x8b7f22cd)}},
+ {{TOBN(0xbbe1500d, 0x084bae24), TOBN(0x2f0ae8d7, 0x343d2693),
+ TOBN(0xacffb5f2, 0x7cdef811), TOBN(0xaa0c030a, 0x263fb94f)},
+ {TOBN(0x6eef0d61, 0xa0f442de), TOBN(0xf92e1817, 0x27b139d3),
+ TOBN(0x1ae6deb7, 0x0ad8bc28), TOBN(0xa89e38dc, 0xc0514130)}},
+ {{TOBN(0x81eeb865, 0xd2fdca23), TOBN(0x5a15ee08, 0xcc8ef895),
+ TOBN(0x768fa10a, 0x01905614), TOBN(0xeff5b8ef, 0x880ee19b)},
+ {TOBN(0xf0c0cabb, 0xcb1c8a0e), TOBN(0x2e1ee9cd, 0xb8c838f9),
+ TOBN(0x0587d8b8, 0x8a4a14c0), TOBN(0xf6f27896, 0x2ff698e5)}},
+ {{TOBN(0xed38ef1c, 0x89ee6256), TOBN(0xf44ee1fe, 0x6b353b45),
+ TOBN(0x9115c0c7, 0x70e903b3), TOBN(0xc78ec0a1, 0x818f31df)},
+ {TOBN(0x6c003324, 0xb7dccbc6), TOBN(0xd96dd1f3, 0x163bbc25),
+ TOBN(0x33aa82dd, 0x5cedd805), TOBN(0x123aae4f, 0x7f7eb2f1)}},
+ {{TOBN(0x1723fcf5, 0xa26262cd), TOBN(0x1f7f4d5d, 0x0060ebd5),
+ TOBN(0xf19c5c01, 0xb2eaa3af), TOBN(0x2ccb9b14, 0x9790accf)},
+ {TOBN(0x1f9c1cad, 0x52324aa6), TOBN(0x63200526, 0x7247df54),
+ TOBN(0x5732fe42, 0xbac96f82), TOBN(0x52fe771f, 0x01a1c384)}},
+ {{TOBN(0x546ca13d, 0xb1001684), TOBN(0xb56b4eee, 0xa1709f75),
+ TOBN(0x266545a9, 0xd5db8672), TOBN(0xed971c90, 0x1e8f3cfb)},
+ {TOBN(0x4e7d8691, 0xe3a07b29), TOBN(0x7570d9ec, 0xe4b696b9),
+ TOBN(0xdc5fa067, 0x7bc7e9ae), TOBN(0x68b44caf, 0xc82c4844)}},
+ {{TOBN(0x519d34b3, 0xbf44da80), TOBN(0x283834f9, 0x5ab32e66),
+ TOBN(0x6e608797, 0x6278a000), TOBN(0x1e62960e, 0x627312f6)},
+ {TOBN(0x9b87b27b, 0xe6901c55), TOBN(0x80e78538, 0x24fdbc1f),
+ TOBN(0xbbbc0951, 0x2facc27d), TOBN(0x06394239, 0xac143b5a)}},
+ {{TOBN(0x35bb4a40, 0x376c1944), TOBN(0x7cb62694, 0x63da1511),
+ TOBN(0xafd29161, 0xb7148a3b), TOBN(0xa6f9d9ed, 0x4e2ea2ee)},
+ {TOBN(0x15dc2ca2, 0x880dd212), TOBN(0x903c3813, 0xa61139a9),
+ TOBN(0x2aa7b46d, 0x6c0f8785), TOBN(0x36ce2871, 0x901c60ff)}},
+ {{TOBN(0xc683b028, 0xe10d9c12), TOBN(0x7573baa2, 0x032f33d3),
+ TOBN(0x87a9b1f6, 0x67a31b58), TOBN(0xfd3ed11a, 0xf4ffae12)},
+ {TOBN(0x83dcaa9a, 0x0cb2748e), TOBN(0x8239f018, 0x5d6fdf16),
+ TOBN(0xba67b49c, 0x72753941), TOBN(0x2beec455, 0xc321cb36)}},
+ {{TOBN(0x88015606, 0x3f8b84ce), TOBN(0x76417083, 0x8d38c86f),
+ TOBN(0x054f1ca7, 0x598953dd), TOBN(0xc939e110, 0x4e8e7429)},
+ {TOBN(0x9b1ac2b3, 0x5a914f2f), TOBN(0x39e35ed3, 0xe74b8f9c),
+ TOBN(0xd0debdb2, 0x781b2fb0), TOBN(0x1585638f, 0x2d997ba2)}},
+ {{TOBN(0x9c4b646e, 0x9e2fce99), TOBN(0x68a21081, 0x1e80857f),
+ TOBN(0x06d54e44, 0x3643b52a), TOBN(0xde8d6d63, 0x0d8eb843)},
+ {TOBN(0x70321563, 0x42146a0a), TOBN(0x8ba826f2, 0x5eaa3622),
+ TOBN(0x227a58bd, 0x86138787), TOBN(0x43b6c03c, 0x10281d37)}},
+ {{TOBN(0x6326afbb, 0xb54dde39), TOBN(0x744e5e8a, 0xdb6f2d5f),
+ TOBN(0x48b2a99a, 0xcff158e1), TOBN(0xa93c8fa0, 0xef87918f)},
+ {TOBN(0x2182f956, 0xde058c5c), TOBN(0x216235d2, 0x936f9e7a),
+ TOBN(0xace0c0db, 0xd2e31e67), TOBN(0xc96449bf, 0xf23ac3e7)}},
+ {{TOBN(0x7e9a2874, 0x170693bd), TOBN(0xa28e14fd, 0xa45e6335),
+ TOBN(0x5757f6b3, 0x56427344), TOBN(0x822e4556, 0xacf8edf9)},
+ {TOBN(0x2b7a6ee2, 0xe6a285cd), TOBN(0x5866f211, 0xa9df3af0),
+ TOBN(0x40dde2dd, 0xf845b844), TOBN(0x986c3726, 0x110e5e49)}},
+ {{TOBN(0x73680c2a, 0xf7172277), TOBN(0x57b94f0f, 0x0cccb244),
+ TOBN(0xbdff7267, 0x2d438ca7), TOBN(0xbad1ce11, 0xcf4663fd)},
+ {TOBN(0x9813ed9d, 0xd8f71cae), TOBN(0xf43272a6, 0x961fdaa6),
+ TOBN(0xbeff0119, 0xbd6d1637), TOBN(0xfebc4f91, 0x30361978)}},
+ {{TOBN(0x02b37a95, 0x2f41deff), TOBN(0x0e44a59a, 0xe63b89b7),
+ TOBN(0x673257dc, 0x143ff951), TOBN(0x19c02205, 0xd752baf4)},
+ {TOBN(0x46c23069, 0xc4b7d692), TOBN(0x2e6392c3, 0xfd1502ac),
+ TOBN(0x6057b1a2, 0x1b220846), TOBN(0xe51ff946, 0x0c1b5b63)}}},
+ {{{TOBN(0x6e85cb51, 0x566c5c43), TOBN(0xcff9c919, 0x3597f046),
+ TOBN(0x9354e90c, 0x4994d94a), TOBN(0xe0a39332, 0x2147927d)},
+ {TOBN(0x8427fac1, 0x0dc1eb2b), TOBN(0x88cfd8c2, 0x2ff319fa),
+ TOBN(0xe2d4e684, 0x01965274), TOBN(0xfa2e067d, 0x67aaa746)}},
+ {{TOBN(0xb6d92a7f, 0x3e5f9f11), TOBN(0x9afe153a, 0xd6cb3b8e),
+ TOBN(0x4d1a6dd7, 0xddf800bd), TOBN(0xf6c13cc0, 0xcaf17e19)},
+ {TOBN(0x15f6c58e, 0x325fc3ee), TOBN(0x71095400, 0xa31dc3b2),
+ TOBN(0x168e7c07, 0xafa3d3e7), TOBN(0x3f8417a1, 0x94c7ae2d)}},
+ {{TOBN(0xec234772, 0x813b230d), TOBN(0x634d0f5f, 0x17344427),
+ TOBN(0x11548ab1, 0xd77fc56a), TOBN(0x7fab1750, 0xce06af77)},
+ {TOBN(0xb62c10a7, 0x4f7c4f83), TOBN(0xa7d2edc4, 0x220a67d9),
+ TOBN(0x1c404170, 0x921209a0), TOBN(0x0b9815a0, 0xface59f0)}},
+ {{TOBN(0x2842589b, 0x319540c3), TOBN(0x18490f59, 0xa283d6f8),
+ TOBN(0xa2731f84, 0xdaae9fcb), TOBN(0x3db6d960, 0xc3683ba0)},
+ {TOBN(0xc85c63bb, 0x14611069), TOBN(0xb19436af, 0x0788bf05),
+ TOBN(0x905459df, 0x347460d2), TOBN(0x73f6e094, 0xe11a7db1)}},
+ {{TOBN(0xdc7f938e, 0xb6357f37), TOBN(0xc5d00f79, 0x2bd8aa62),
+ TOBN(0xc878dcb9, 0x2ca979fc), TOBN(0x37e83ed9, 0xeb023a99)},
+ {TOBN(0x6b23e273, 0x1560bf3d), TOBN(0x1086e459, 0x1d0fae61),
+ TOBN(0x78248316, 0x9a9414bd), TOBN(0x1b956bc0, 0xf0ea9ea1)}},
+ {{TOBN(0x7b85bb91, 0xc31b9c38), TOBN(0x0c5aa90b, 0x48ef57b5),
+ TOBN(0xdedeb169, 0xaf3bab6f), TOBN(0xe610ad73, 0x2d373685)},
+ {TOBN(0xf13870df, 0x02ba8e15), TOBN(0x0337edb6, 0x8ca7f771),
+ TOBN(0xe4acf747, 0xb62c036c), TOBN(0xd921d576, 0xb6b94e81)}},
+ {{TOBN(0xdbc86439, 0x2c422f7a), TOBN(0xfb635362, 0xed348898),
+ TOBN(0x83084668, 0xc45bfcd1), TOBN(0xc357c9e3, 0x2b315e11)},
+ {TOBN(0xb173b540, 0x5b2e5b8c), TOBN(0x7e946931, 0xe102b9a4),
+ TOBN(0x17c890eb, 0x7b0fb199), TOBN(0xec225a83, 0xd61b662b)}},
+ {{TOBN(0xf306a3c8, 0xee3c76cb), TOBN(0x3cf11623, 0xd32a1f6e),
+ TOBN(0xe6d5ab64, 0x6863e956), TOBN(0x3b8a4cbe, 0x5c005c26)},
+ {TOBN(0xdcd529a5, 0x9ce6bb27), TOBN(0xc4afaa52, 0x04d4b16f),
+ TOBN(0xb0624a26, 0x7923798d), TOBN(0x85e56df6, 0x6b307fab)}},
+ {{TOBN(0x0281893c, 0x2bf29698), TOBN(0x91fc19a4, 0xd7ce7603),
+ TOBN(0x75a5dca3, 0xad9a558f), TOBN(0x40ceb3fa, 0x4d50bf77)},
+ {TOBN(0x1baf6060, 0xbc9ba369), TOBN(0x927e1037, 0x597888c2),
+ TOBN(0xd936bf19, 0x86a34c07), TOBN(0xd4cf10c1, 0xc34ae980)}},
+ {{TOBN(0x3a3e5334, 0x859dd614), TOBN(0x9c475b5b, 0x18d0c8ee),
+ TOBN(0x63080d1f, 0x07cd51d5), TOBN(0xc9c0d0a6, 0xb88b4326)},
+ {TOBN(0x1ac98691, 0xc234296f), TOBN(0x2a0a83a4, 0x94887fb6),
+ TOBN(0x56511427, 0x0cea9cf2), TOBN(0x5230a6e8, 0xa24802f5)}},
+ {{TOBN(0xf7a2bf0f, 0x72e3d5c1), TOBN(0x37717446, 0x4f21439e),
+ TOBN(0xfedcbf25, 0x9ce30334), TOBN(0xe0030a78, 0x7ce202f9)},
+ {TOBN(0x6f2d9ebf, 0x1202e9ca), TOBN(0xe79dde6c, 0x75e6e591),
+ TOBN(0xf52072af, 0xf1dac4f8), TOBN(0x6c8d087e, 0xbb9b404d)}},
+ {{TOBN(0xad0fc73d, 0xbce913af), TOBN(0x909e587b, 0x458a07cb),
+ TOBN(0x1300da84, 0xd4f00c8a), TOBN(0x425cd048, 0xb54466ac)},
+ {TOBN(0xb59cb9be, 0x90e9d8bf), TOBN(0x991616db, 0x3e431b0e),
+ TOBN(0xd3aa117a, 0x531aecff), TOBN(0x91af92d3, 0x59f4dc3b)}},
+ {{TOBN(0x9b1ec292, 0xe93fda29), TOBN(0x76bb6c17, 0xe97d91bc),
+ TOBN(0x7509d95f, 0xaface1e6), TOBN(0x3653fe47, 0xbe855ae3)},
+ {TOBN(0x73180b28, 0x0f680e75), TOBN(0x75eefd1b, 0xeeb6c26c),
+ TOBN(0xa4cdf29f, 0xb66d4236), TOBN(0x2d70a997, 0x6b5821d8)}},
+ {{TOBN(0x7a3ee207, 0x20445c36), TOBN(0x71d1ac82, 0x59877174),
+ TOBN(0x0fc539f7, 0x949f73e9), TOBN(0xd05cf3d7, 0x982e3081)},
+ {TOBN(0x8758e20b, 0x7b1c7129), TOBN(0xffadcc20, 0x569e61f2),
+ TOBN(0xb05d3a2f, 0x59544c2d), TOBN(0xbe16f5c1, 0x9fff5e53)}},
+ {{TOBN(0x73cf65b8, 0xaad58135), TOBN(0x622c2119, 0x037aa5be),
+ TOBN(0x79373b3f, 0x646fd6a0), TOBN(0x0e029db5, 0x0d3978cf)},
+ {TOBN(0x8bdfc437, 0x94fba037), TOBN(0xaefbd687, 0x620797a6),
+ TOBN(0x3fa5382b, 0xbd30d38e), TOBN(0x7627cfbf, 0x585d7464)}},
+ {{TOBN(0xb2330fef, 0x4e4ca463), TOBN(0xbcef7287, 0x3566cc63),
+ TOBN(0xd161d2ca, 0xcf780900), TOBN(0x135dc539, 0x5b54827d)},
+ {TOBN(0x638f052e, 0x27bf1bc6), TOBN(0x10a224f0, 0x07dfa06c),
+ TOBN(0xe973586d, 0x6d3321da), TOBN(0x8b0c5738, 0x26152c8f)}},
+ {{TOBN(0x07ef4f2a, 0x34606074), TOBN(0x80fe7fe8, 0xa0f7047a),
+ TOBN(0x3d1a8152, 0xe1a0e306), TOBN(0x32cf43d8, 0x88da5222)},
+ {TOBN(0xbf89a95f, 0x5f02ffe6), TOBN(0x3d9eb9a4, 0x806ad3ea),
+ TOBN(0x012c17bb, 0x79c8e55e), TOBN(0xfdcd1a74, 0x99c81dac)}},
+ {{TOBN(0x7043178b, 0xb9556098), TOBN(0x4090a1df, 0x801c3886),
+ TOBN(0x759800ff, 0x9b67b912), TOBN(0x3e5c0304, 0x232620c8)},
+ {TOBN(0x4b9d3c4b, 0x70dceeca), TOBN(0xbb2d3c15, 0x181f648e),
+ TOBN(0xf981d837, 0x6e33345c), TOBN(0xb626289b, 0x0cf2297a)}},
+ {{TOBN(0x766ac659, 0x8baebdcf), TOBN(0x1a28ae09, 0x75df01e5),
+ TOBN(0xb71283da, 0x375876d8), TOBN(0x4865a96d, 0x607b9800)},
+ {TOBN(0x25dd1bcd, 0x237936b2), TOBN(0x332f4f4b, 0x60417494),
+ TOBN(0xd0923d68, 0x370a2147), TOBN(0x497f5dfb, 0xdc842203)}},
+ {{TOBN(0x9dc74cbd, 0x32be5e0f), TOBN(0x7475bcb7, 0x17a01375),
+ TOBN(0x438477c9, 0x50d872b1), TOBN(0xcec67879, 0xffe1d63d)},
+ {TOBN(0x9b006014, 0xd8578c70), TOBN(0xc9ad99a8, 0x78bb6b8b),
+ TOBN(0x6799008e, 0x11fb3806), TOBN(0xcfe81435, 0xcd44cab3)}},
+ {{TOBN(0xa2ee1582, 0x2f4fb344), TOBN(0xb8823450, 0x483fa6eb),
+ TOBN(0x622d323d, 0x652c7749), TOBN(0xd8474a98, 0xbeb0a15b)},
+ {TOBN(0xe43c154d, 0x5d1c00d0), TOBN(0x7fd581d9, 0x0e3e7aac),
+ TOBN(0x2b44c619, 0x2525ddf8), TOBN(0x67a033eb, 0xb8ae9739)}},
+ {{TOBN(0x113ffec1, 0x9ef2d2e4), TOBN(0x1bf6767e, 0xd5a0ea7f),
+ TOBN(0x57fff75e, 0x03714c0a), TOBN(0xa23c422e, 0x0a23e9ee)},
+ {TOBN(0xdd5f6b2d, 0x540f83af), TOBN(0xc2c2c27e, 0x55ea46a7),
+ TOBN(0xeb6b4246, 0x672a1208), TOBN(0xd13599f7, 0xae634f7a)}},
+ {{TOBN(0xcf914b5c, 0xd7b32c6e), TOBN(0x61a5a640, 0xeaf61814),
+ TOBN(0x8dc3df8b, 0x208a1bbb), TOBN(0xef627fd6, 0xb6d79aa5)},
+ {TOBN(0x44232ffc, 0xc4c86bc8), TOBN(0xe6f9231b, 0x061539fe),
+ TOBN(0x1d04f25a, 0x958b9533), TOBN(0x180cf934, 0x49e8c885)}},
+ {{TOBN(0x89689595, 0x9884aaf7), TOBN(0xb1959be3, 0x07b348a6),
+ TOBN(0x96250e57, 0x3c147c87), TOBN(0xae0efb3a, 0xdd0c61f8)},
+ {TOBN(0xed00745e, 0xca8c325e), TOBN(0x3c911696, 0xecff3f70),
+ TOBN(0x73acbc65, 0x319ad41d), TOBN(0x7b01a020, 0xf0b1c7ef)}},
+ {{TOBN(0xea32b293, 0x63a1483f), TOBN(0x89eabe71, 0x7a248f96),
+ TOBN(0x9c6231d3, 0x343157e5), TOBN(0x93a375e5, 0xdf3c546d)},
+ {TOBN(0xe76e9343, 0x6a2afe69), TOBN(0xc4f89100, 0xe166c88e),
+ TOBN(0x248efd0d, 0x4f872093), TOBN(0xae0eb3ea, 0x8fe0ea61)}},
+ {{TOBN(0xaf89790d, 0x9d79046e), TOBN(0x4d650f2d, 0x6cee0976),
+ TOBN(0xa3935d9a, 0x43071eca), TOBN(0x66fcd2c9, 0x283b0bfe)},
+ {TOBN(0x0e665eb5, 0x696605f1), TOBN(0xe77e5d07, 0xa54cd38d),
+ TOBN(0x90ee050a, 0x43d950cf), TOBN(0x86ddebda, 0xd32e69b5)}},
+ {{TOBN(0x6ad94a3d, 0xfddf7415), TOBN(0xf7fa1309, 0x3f6e8d5a),
+ TOBN(0xc4831d1d, 0xe9957f75), TOBN(0x7de28501, 0xd5817447)},
+ {TOBN(0x6f1d7078, 0x9e2aeb6b), TOBN(0xba2b9ff4, 0xf67a53c2),
+ TOBN(0x36963767, 0xdf9defc3), TOBN(0x479deed3, 0x0d38022c)}},
+ {{TOBN(0xd2edb89b, 0x3a8631e8), TOBN(0x8de855de, 0x7a213746),
+ TOBN(0xb2056cb7, 0xb00c5f11), TOBN(0xdeaefbd0, 0x2c9b85e4)},
+ {TOBN(0x03f39a8d, 0xd150892d), TOBN(0x37b84686, 0x218b7985),
+ TOBN(0x36296dd8, 0xb7375f1a), TOBN(0x472cd4b1, 0xb78e898e)}},
+ {{TOBN(0x15dff651, 0xe9f05de9), TOBN(0xd4045069, 0x2ce98ba9),
+ TOBN(0x8466a7ae, 0x9b38024c), TOBN(0xb910e700, 0xe5a6b5ef)},
+ {TOBN(0xae1c56ea, 0xb3aa8f0d), TOBN(0xbab2a507, 0x7eee74a6),
+ TOBN(0x0dca11e2, 0x4b4c4620), TOBN(0xfd896e2e, 0x4c47d1f4)}},
+ {{TOBN(0xeb45ae53, 0x308fbd93), TOBN(0x46cd5a2e, 0x02c36fda),
+ TOBN(0x6a3d4e90, 0xbaa48385), TOBN(0xdd55e62e, 0x9dbe9960)},
+ {TOBN(0xa1406aa0, 0x2a81ede7), TOBN(0x6860dd14, 0xf9274ea7),
+ TOBN(0xcfdcb0c2, 0x80414f86), TOBN(0xff410b10, 0x22f94327)}},
+ {{TOBN(0x5a33cc38, 0x49ad467b), TOBN(0xefb48b6c, 0x0a7335f1),
+ TOBN(0x14fb54a4, 0xb153a360), TOBN(0x604aa9d2, 0xb52469cc)},
+ {TOBN(0x5e9dc486, 0x754e48e9), TOBN(0x693cb455, 0x37471e8e),
+ TOBN(0xfb2fd7cd, 0x8d3b37b6), TOBN(0x63345e16, 0xcf09ff07)}},
+ {{TOBN(0x9910ba6b, 0x23a5d896), TOBN(0x1fe19e35, 0x7fe4364e),
+ TOBN(0x6e1da8c3, 0x9a33c677), TOBN(0x15b4488b, 0x29fd9fd0)},
+ {TOBN(0x1f439254, 0x1a1f22bf), TOBN(0x920a8a70, 0xab8163e8),
+ TOBN(0x3fd1b249, 0x07e5658e), TOBN(0xf2c4f79c, 0xb6ec839b)}},
+ {{TOBN(0x1abbc3d0, 0x4aa38d1b), TOBN(0x3b0db35c, 0xb5d9510e),
+ TOBN(0x1754ac78, 0x3e60dec0), TOBN(0x53272fd7, 0xea099b33)},
+ {TOBN(0x5fb0494f, 0x07a8e107), TOBN(0x4a89e137, 0x6a8191fa),
+ TOBN(0xa113b7f6, 0x3c4ad544), TOBN(0x88a2e909, 0x6cb9897b)}},
+ {{TOBN(0x17d55de3, 0xb44a3f84), TOBN(0xacb2f344, 0x17c6c690),
+ TOBN(0x32088168, 0x10232390), TOBN(0xf2e8a61f, 0x6c733bf7)},
+ {TOBN(0xa774aab6, 0x9c2d7652), TOBN(0xfb5307e3, 0xed95c5bc),
+ TOBN(0xa05c73c2, 0x4981f110), TOBN(0x1baae31c, 0xa39458c9)}},
+ {{TOBN(0x1def185b, 0xcbea62e7), TOBN(0xe8ac9eae, 0xeaf63059),
+ TOBN(0x098a8cfd, 0x9921851c), TOBN(0xd959c3f1, 0x3abe2f5b)},
+ {TOBN(0xa4f19525, 0x20e40ae5), TOBN(0x320789e3, 0x07a24aa1),
+ TOBN(0x259e6927, 0x7392b2bc), TOBN(0x58f6c667, 0x1918668b)}},
+ {{TOBN(0xce1db2bb, 0xc55d2d8b), TOBN(0x41d58bb7, 0xf4f6ca56),
+ TOBN(0x7650b680, 0x8f877614), TOBN(0x905e16ba, 0xf4c349ed)},
+ {TOBN(0xed415140, 0xf661acac), TOBN(0x3b8784f0, 0xcb2270af),
+ TOBN(0x3bc280ac, 0x8a402cba), TOBN(0xd53f7146, 0x0937921a)}},
+ {{TOBN(0xc03c8ee5, 0xe5681e83), TOBN(0x62126105, 0xf6ac9e4a),
+ TOBN(0x9503a53f, 0x936b1a38), TOBN(0x3d45e2d4, 0x782fecbd)},
+ {TOBN(0x69a5c439, 0x76e8ae98), TOBN(0xb53b2eeb, 0xbfb4b00e),
+ TOBN(0xf1674712, 0x72386c89), TOBN(0x30ca34a2, 0x4268bce4)}},
+ {{TOBN(0x7f1ed86c, 0x78341730), TOBN(0x8ef5beb8, 0xb525e248),
+ TOBN(0xbbc489fd, 0xb74fbf38), TOBN(0x38a92a0e, 0x91a0b382)},
+ {TOBN(0x7a77ba3f, 0x22433ccf), TOBN(0xde8362d6, 0xa29f05a9),
+ TOBN(0x7f6a30ea, 0x61189afc), TOBN(0x693b5505, 0x59ef114f)}},
+ {{TOBN(0x50266bc0, 0xcd1797a1), TOBN(0xea17b47e, 0xf4b7af2d),
+ TOBN(0xd6c4025c, 0x3df9483e), TOBN(0x8cbb9d9f, 0xa37b18c9)},
+ {TOBN(0x91cbfd9c, 0x4d8424cf), TOBN(0xdb7048f1, 0xab1c3506),
+ TOBN(0x9eaf641f, 0x028206a3), TOBN(0xf986f3f9, 0x25bdf6ce)}},
+ {{TOBN(0x262143b5, 0x224c08dc), TOBN(0x2bbb09b4, 0x81b50c91),
+ TOBN(0xc16ed709, 0xaca8c84f), TOBN(0xa6210d9d, 0xb2850ca8)},
+ {TOBN(0x6d8df67a, 0x09cb54d6), TOBN(0x91eef6e0, 0x500919a4),
+ TOBN(0x90f61381, 0x0f132857), TOBN(0x9acede47, 0xf8d5028b)}},
+ {{TOBN(0x844d1b71, 0x90b771c3), TOBN(0x563b71e4, 0xba6426be),
+ TOBN(0x2efa2e83, 0xbdb802ff), TOBN(0x3410cbab, 0xab5b4a41)},
+ {TOBN(0x555b2d26, 0x30da84dd), TOBN(0xd0711ae9, 0xee1cc29a),
+ TOBN(0xcf3e8c60, 0x2f547792), TOBN(0x03d7d5de, 0xdc678b35)}},
+ {{TOBN(0x071a2fa8, 0xced806b8), TOBN(0x222e6134, 0x697f1478),
+ TOBN(0xdc16fd5d, 0xabfcdbbf), TOBN(0x44912ebf, 0x121b53b8)},
+ {TOBN(0xac943674, 0x2496c27c), TOBN(0x8ea3176c, 0x1ffc26b0),
+ TOBN(0xb6e224ac, 0x13debf2c), TOBN(0x524cc235, 0xf372a832)}},
+ {{TOBN(0xd706e1d8, 0x9f6f1b18), TOBN(0x2552f005, 0x44cce35b),
+ TOBN(0x8c8326c2, 0xa88e31fc), TOBN(0xb5468b2c, 0xf9552047)},
+ {TOBN(0xce683e88, 0x3ff90f2b), TOBN(0x77947bdf, 0x2f0a5423),
+ TOBN(0xd0a1b28b, 0xed56e328), TOBN(0xaee35253, 0xc20134ac)}},
+ {{TOBN(0x7e98367d, 0x3567962f), TOBN(0x379ed61f, 0x8188bffb),
+ TOBN(0x73bba348, 0xfaf130a1), TOBN(0x6c1f75e1, 0x904ed734)},
+ {TOBN(0x18956642, 0x3b4a79fc), TOBN(0xf20bc83d, 0x54ef4493),
+ TOBN(0x836d425d, 0x9111eca1), TOBN(0xe5b5c318, 0x009a8dcf)}},
+ {{TOBN(0x3360b25d, 0x13221bc5), TOBN(0x707baad2, 0x6b3eeaf7),
+ TOBN(0xd7279ed8, 0x743a95a1), TOBN(0x7450a875, 0x969e809f)},
+ {TOBN(0x32b6bd53, 0xe5d0338f), TOBN(0x1e77f7af, 0x2b883bbc),
+ TOBN(0x90da12cc, 0x1063ecd0), TOBN(0xe2697b58, 0xc315be47)}},
+ {{TOBN(0x2771a5bd, 0xda85d534), TOBN(0x53e78c1f, 0xff980eea),
+ TOBN(0xadf1cf84, 0x900385e7), TOBN(0x7d3b14f6, 0xc9387b62)},
+ {TOBN(0x170e74b0, 0xcb8f2bd2), TOBN(0x2d50b486, 0x827fa993),
+ TOBN(0xcdbe8c9a, 0xf6f32bab), TOBN(0x55e906b0, 0xc3b93ab8)}},
+ {{TOBN(0x747f22fc, 0x8fe280d1), TOBN(0xcd8e0de5, 0xb2e114ab),
+ TOBN(0x5ab7dbeb, 0xe10b68b0), TOBN(0x9dc63a9c, 0xa480d4b2)},
+ {TOBN(0x78d4bc3b, 0x4be1495f), TOBN(0x25eb3db8, 0x9359122d),
+ TOBN(0x3f8ac05b, 0x0809cbdc), TOBN(0xbf4187bb, 0xd37c702f)}},
+ {{TOBN(0x84cea069, 0x1416a6a5), TOBN(0x8f860c79, 0x43ef881c),
+ TOBN(0x41311f8a, 0x38038a5d), TOBN(0xe78c2ec0, 0xfc612067)},
+ {TOBN(0x494d2e81, 0x5ad73581), TOBN(0xb4cc9e00, 0x59604097),
+ TOBN(0xff558aec, 0xf3612cba), TOBN(0x35beef7a, 0x9e36c39e)}},
+ {{TOBN(0x1845c7cf, 0xdbcf41b9), TOBN(0x5703662a, 0xaea997c0),
+ TOBN(0x8b925afe, 0xe402f6d8), TOBN(0xd0a1b1ae, 0x4dd72162)},
+ {TOBN(0x9f47b375, 0x03c41c4b), TOBN(0xa023829b, 0x0391d042),
+ TOBN(0x5f5045c3, 0x503b8b0a), TOBN(0x123c2688, 0x98c010e5)}},
+ {{TOBN(0x324ec0cc, 0x36ba06ee), TOBN(0xface3115, 0x3dd2cc0c),
+ TOBN(0xb364f3be, 0xf333e91f), TOBN(0xef8aff73, 0x28e832b0)},
+ {TOBN(0x1e9bad04, 0x2d05841b), TOBN(0x42f0e3df, 0x356a21e2),
+ TOBN(0xa3270bcb, 0x4add627e), TOBN(0xb09a8158, 0xd322e711)}},
+ {{TOBN(0x86e326a1, 0x0fee104a), TOBN(0xad7788f8, 0x3703f65d),
+ TOBN(0x7e765430, 0x47bc4833), TOBN(0x6cee582b, 0x2b9b893a)},
+ {TOBN(0x9cd2a167, 0xe8f55a7b), TOBN(0xefbee3c6, 0xd9e4190d),
+ TOBN(0x33ee7185, 0xd40c2e9d), TOBN(0x844cc9c5, 0xa380b548)}},
+ {{TOBN(0x323f8ecd, 0x66926e04), TOBN(0x0001e38f, 0x8110c1ba),
+ TOBN(0x8dbcac12, 0xfc6a7f07), TOBN(0xd65e1d58, 0x0cec0827)},
+ {TOBN(0xd2cd4141, 0xbe76ca2d), TOBN(0x7895cf5c, 0xe892f33a),
+ TOBN(0x956d230d, 0x367139d2), TOBN(0xa91abd3e, 0xd012c4c1)}},
+ {{TOBN(0x34fa4883, 0x87eb36bf), TOBN(0xc5f07102, 0x914b8fb4),
+ TOBN(0x90f0e579, 0xadb9c95f), TOBN(0xfe6ea8cb, 0x28888195)},
+ {TOBN(0x7b9b5065, 0xedfa9284), TOBN(0x6c510bd2, 0x2b8c8d65),
+ TOBN(0xd7b8ebef, 0xcbe8aafd), TOBN(0xedb3af98, 0x96b1da07)}},
+ {{TOBN(0x28ff779d, 0x6295d426), TOBN(0x0c4f6ac7, 0x3fa3ad7b),
+ TOBN(0xec44d054, 0x8b8e2604), TOBN(0x9b32a66d, 0x8b0050e1)},
+ {TOBN(0x1f943366, 0xf0476ce2), TOBN(0x7554d953, 0xa602c7b4),
+ TOBN(0xbe35aca6, 0x524f2809), TOBN(0xb6881229, 0xfd4edbea)}},
+ {{TOBN(0xe8cd0c8f, 0x508efb63), TOBN(0x9eb5b5c8, 0x6abcefc7),
+ TOBN(0xf5621f5f, 0xb441ab4f), TOBN(0x79e6c046, 0xb76a2b22)},
+ {TOBN(0x74a4792c, 0xe37a1f69), TOBN(0xcbd252cb, 0x03542b60),
+ TOBN(0x785f65d5, 0xb3c20bd3), TOBN(0x8dea6143, 0x4fabc60c)}},
+ {{TOBN(0x45e21446, 0xde673629), TOBN(0x57f7aa1e, 0x703c2d21),
+ TOBN(0xa0e99b7f, 0x98c868c7), TOBN(0x4e42f66d, 0x8b641676)},
+ {TOBN(0x602884dc, 0x91077896), TOBN(0xa0d690cf, 0xc2c9885b),
+ TOBN(0xfeb4da33, 0x3b9a5187), TOBN(0x5f789598, 0x153c87ee)}},
+ {{TOBN(0x2192dd47, 0x52b16dba), TOBN(0xdeefc0e6, 0x3524c1b1),
+ TOBN(0x465ea76e, 0xe4383693), TOBN(0x79401711, 0x361b8d98)},
+ {TOBN(0xa5f9ace9, 0xf21a15cb), TOBN(0x73d26163, 0xefee9aeb),
+ TOBN(0xcca844b3, 0xe677016c), TOBN(0x6c122b07, 0x57eaee06)}},
+ {{TOBN(0xb782dce7, 0x15f09690), TOBN(0x508b9b12, 0x2dfc0fc9),
+ TOBN(0x9015ab4b, 0x65d89fc6), TOBN(0x5e79dab7, 0xd6d5bb0f)},
+ {TOBN(0x64f021f0, 0x6c775aa2), TOBN(0xdf09d8cc, 0x37c7eca1),
+ TOBN(0x9a761367, 0xef2fa506), TOBN(0xed4ca476, 0x5b81eec6)}},
+ {{TOBN(0x262ede36, 0x10bbb8b5), TOBN(0x0737ce83, 0x0641ada3),
+ TOBN(0x4c94288a, 0xe9831ccc), TOBN(0x487fc1ce, 0x8065e635)},
+ {TOBN(0xb13d7ab3, 0xb8bb3659), TOBN(0xdea5df3e, 0x855e4120),
+ TOBN(0xb9a18573, 0x85eb0244), TOBN(0x1a1b8ea3, 0xa7cfe0a3)}},
+ {{TOBN(0x3b837119, 0x67b0867c), TOBN(0x8d5e0d08, 0x9d364520),
+ TOBN(0x52dccc1e, 0xd930f0e3), TOBN(0xefbbcec7, 0xbf20bbaf)},
+ {TOBN(0x99cffcab, 0x0263ad10), TOBN(0xd8199e6d, 0xfcd18f8a),
+ TOBN(0x64e2773f, 0xe9f10617), TOBN(0x0079e8e1, 0x08704848)}},
+ {{TOBN(0x1169989f, 0x8a342283), TOBN(0x8097799c, 0xa83012e6),
+ TOBN(0xece966cb, 0x8a6a9001), TOBN(0x93b3afef, 0x072ac7fc)},
+ {TOBN(0xe6893a2a, 0x2db3d5ba), TOBN(0x263dc462, 0x89bf4fdc),
+ TOBN(0x8852dfc9, 0xe0396673), TOBN(0x7ac70895, 0x3af362b6)}},
+ {{TOBN(0xbb9cce4d, 0x5c2f342b), TOBN(0xbf80907a, 0xb52d7aae),
+ TOBN(0x97f3d3cd, 0x2161bcd0), TOBN(0xb25b0834, 0x0962744d)},
+ {TOBN(0xc5b18ea5, 0x6c3a1dda), TOBN(0xfe4ec7eb, 0x06c92317),
+ TOBN(0xb787b890, 0xad1c4afe), TOBN(0xdccd9a92, 0x0ede801a)}},
+ {{TOBN(0x9ac6ddda, 0xdb58da1f), TOBN(0x22bbc12f, 0xb8cae6ee),
+ TOBN(0xc6f8bced, 0x815c4a43), TOBN(0x8105a92c, 0xf96480c7)},
+ {TOBN(0x0dc3dbf3, 0x7a859d51), TOBN(0xe3ec7ce6, 0x3041196b),
+ TOBN(0xd9f64b25, 0x0d1067c9), TOBN(0xf2321321, 0x3d1f8dd8)}},
+ {{TOBN(0x8b5c619c, 0x76497ee8), TOBN(0x5d2b0ac6, 0xc717370e),
+ TOBN(0x98204cb6, 0x4fcf68e1), TOBN(0x0bdec211, 0x62bc6792)},
+ {TOBN(0x6973ccef, 0xa63b1011), TOBN(0xf9e3fa97, 0xe0de1ac5),
+ TOBN(0x5efb693e, 0x3d0e0c8b), TOBN(0x037248e9, 0xd2d4fcb4)}}},
+ {{{TOBN(0x80802dc9, 0x1ec34f9e), TOBN(0xd8772d35, 0x33810603),
+ TOBN(0x3f06d66c, 0x530cb4f3), TOBN(0x7be5ed0d, 0xc475c129)},
+ {TOBN(0xcb9e3c19, 0x31e82b10), TOBN(0xc63d2857, 0xc9ff6b4c),
+ TOBN(0xb92118c6, 0x92a1b45e), TOBN(0x0aec4414, 0x7285bbca)}},
+ {{TOBN(0xfc189ae7, 0x1e29a3ef), TOBN(0xcbe906f0, 0x4c93302e),
+ TOBN(0xd0107914, 0xceaae10e), TOBN(0xb7a23f34, 0xb68e19f8)},
+ {TOBN(0xe9d875c2, 0xefd2119d), TOBN(0x03198c6e, 0xfcadc9c8),
+ TOBN(0x65591bf6, 0x4da17113), TOBN(0x3cf0bbf8, 0x3d443038)}},
+ {{TOBN(0xae485bb7, 0x2b724759), TOBN(0x945353e1, 0xb2d4c63a),
+ TOBN(0x82159d07, 0xde7d6f2c), TOBN(0x389caef3, 0x4ec5b109)},
+ {TOBN(0x4a8ebb53, 0xdb65ef14), TOBN(0x2dc2cb7e, 0xdd99de43),
+ TOBN(0x816fa3ed, 0x83f2405f), TOBN(0x73429bb9, 0xc14208a3)}},
+ {{TOBN(0xb618d590, 0xb01e6e27), TOBN(0x047e2ccd, 0xe180b2dc),
+ TOBN(0xd1b299b5, 0x04aea4a9), TOBN(0x412c9e1e, 0x9fa403a4)},
+ {TOBN(0x88d28a36, 0x79407552), TOBN(0x49c50136, 0xf332b8e3),
+ TOBN(0x3a1b6fcc, 0xe668de19), TOBN(0x178851bc, 0x75122b97)}},
+ {{TOBN(0xb1e13752, 0xfb85fa4c), TOBN(0xd61257ce, 0x383c8ce9),
+ TOBN(0xd43da670, 0xd2f74dae), TOBN(0xa35aa23f, 0xbf846bbb)},
+ {TOBN(0x5e74235d, 0x4421fc83), TOBN(0xf6df8ee0, 0xc363473b),
+ TOBN(0x34d7f52a, 0x3c4aa158), TOBN(0x50d05aab, 0x9bc6d22e)}},
+ {{TOBN(0x8c56e735, 0xa64785f4), TOBN(0xbc56637b, 0x5f29cd07),
+ TOBN(0x53b2bb80, 0x3ee35067), TOBN(0x50235a0f, 0xdc919270)},
+ {TOBN(0x191ab6d8, 0xf2c4aa65), TOBN(0xc3475831, 0x8396023b),
+ TOBN(0x80400ba5, 0xf0f805ba), TOBN(0x8881065b, 0x5ec0f80f)}},
+ {{TOBN(0xc370e522, 0xcc1b5e83), TOBN(0xde2d4ad1, 0x860b8bfb),
+ TOBN(0xad364df0, 0x67b256df), TOBN(0x8f12502e, 0xe0138997)},
+ {TOBN(0x503fa0dc, 0x7783920a), TOBN(0xe80014ad, 0xc0bc866a),
+ TOBN(0x3f89b744, 0xd3064ba6), TOBN(0x03511dcd, 0xcba5dba5)}},
+ {{TOBN(0x197dd46d, 0x95a7b1a2), TOBN(0x9c4e7ad6, 0x3c6341fb),
+ TOBN(0x426eca29, 0x484c2ece), TOBN(0x9211e489, 0xde7f4f8a)},
+ {TOBN(0x14997f6e, 0xc78ef1f4), TOBN(0x2b2c0910, 0x06574586),
+ TOBN(0x17286a6e, 0x1c3eede8), TOBN(0x25f92e47, 0x0f60e018)}},
+ {{TOBN(0x805c5646, 0x31890a36), TOBN(0x703ef600, 0x57feea5b),
+ TOBN(0x389f747c, 0xaf3c3030), TOBN(0xe0e5daeb, 0x54dd3739)},
+ {TOBN(0xfe24a4c3, 0xc9c9f155), TOBN(0x7e4bf176, 0xb5393962),
+ TOBN(0x37183de2, 0xaf20bf29), TOBN(0x4a1bd7b5, 0xf95a8c3b)}},
+ {{TOBN(0xa83b9699, 0x46191d3d), TOBN(0x281fc8dd, 0x7b87f257),
+ TOBN(0xb18e2c13, 0x54107588), TOBN(0x6372def7, 0x9b2bafe8)},
+ {TOBN(0xdaf4bb48, 0x0d8972ca), TOBN(0x3f2dd4b7, 0x56167a3f),
+ TOBN(0x1eace32d, 0x84310cf4), TOBN(0xe3bcefaf, 0xe42700aa)}},
+ {{TOBN(0x5fe5691e, 0xd785e73d), TOBN(0xa5db5ab6, 0x2ea60467),
+ TOBN(0x02e23d41, 0xdfc6514a), TOBN(0x35e8048e, 0xe03c3665)},
+ {TOBN(0x3f8b118f, 0x1adaa0f8), TOBN(0x28ec3b45, 0x84ce1a5a),
+ TOBN(0xe8cacc6e, 0x2c6646b8), TOBN(0x1343d185, 0xdbd0e40f)}},
+ {{TOBN(0xe5d7f844, 0xcaaa358c), TOBN(0x1a1db7e4, 0x9924182a),
+ TOBN(0xd64cd42d, 0x9c875d9a), TOBN(0xb37b515f, 0x042eeec8)},
+ {TOBN(0x4d4dd409, 0x7b165fbe), TOBN(0xfc322ed9, 0xe206eff3),
+ TOBN(0x7dee4102, 0x59b7e17e), TOBN(0x55a481c0, 0x8236ca00)}},
+ {{TOBN(0x8c885312, 0xc23fc975), TOBN(0x15715806, 0x05d6297b),
+ TOBN(0xa078868e, 0xf78edd39), TOBN(0x956b31e0, 0x03c45e52)},
+ {TOBN(0x470275d5, 0xff7b33a6), TOBN(0xc8d5dc3a, 0x0c7e673f),
+ TOBN(0x419227b4, 0x7e2f2598), TOBN(0x8b37b634, 0x4c14a975)}},
+ {{TOBN(0xd0667ed6, 0x8b11888c), TOBN(0x5e0e8c3e, 0x803e25dc),
+ TOBN(0x34e5d0dc, 0xb987a24a), TOBN(0x9f40ac3b, 0xae920323)},
+ {TOBN(0x5463de95, 0x34e0f63a), TOBN(0xa128bf92, 0x6b6328f9),
+ TOBN(0x491ccd7c, 0xda64f1b7), TOBN(0x7ef1ec27, 0xc47bde35)}},
+ {{TOBN(0xa857240f, 0xa36a2737), TOBN(0x35dc1366, 0x63621bc1),
+ TOBN(0x7a3a6453, 0xd4fb6897), TOBN(0x80f1a439, 0xc929319d)},
+ {TOBN(0xfc18274b, 0xf8cb0ba0), TOBN(0xb0b53766, 0x8078c5eb),
+ TOBN(0xfb0d4924, 0x1e01d0ef), TOBN(0x50d7c67d, 0x372ab09c)}},
+ {{TOBN(0xb4e370af, 0x3aeac968), TOBN(0xe4f7fee9, 0xc4b63266),
+ TOBN(0xb4acd4c2, 0xe3ac5664), TOBN(0xf8910bd2, 0xceb38cbf)},
+ {TOBN(0x1c3ae50c, 0xc9c0726e), TOBN(0x15309569, 0xd97b40bf),
+ TOBN(0x70884b7f, 0xfd5a5a1b), TOBN(0x3890896a, 0xef8314cd)}},
+ {{TOBN(0x58e1515c, 0xa5618c93), TOBN(0xe665432b, 0x77d942d1),
+ TOBN(0xb32181bf, 0xb6f767a8), TOBN(0x753794e8, 0x3a604110)},
+ {TOBN(0x09afeb7c, 0xe8c0dbcc), TOBN(0x31e02613, 0x598673a3),
+ TOBN(0x5d98e557, 0x7d46db00), TOBN(0xfc21fb8c, 0x9d985b28)}},
+ {{TOBN(0xc9040116, 0xb0843e0b), TOBN(0x53b1b3a8, 0x69b04531),
+ TOBN(0xdd1649f0, 0x85d7d830), TOBN(0xbb3bcc87, 0xcb7427e8)},
+ {TOBN(0x77261100, 0xc93dce83), TOBN(0x7e79da61, 0xa1922a2a),
+ TOBN(0x587a2b02, 0xf3149ce8), TOBN(0x147e1384, 0xde92ec83)}},
+ {{TOBN(0x484c83d3, 0xaf077f30), TOBN(0xea78f844, 0x0658b53a),
+ TOBN(0x912076c2, 0x027aec53), TOBN(0xf34714e3, 0x93c8177d)},
+ {TOBN(0x37ef5d15, 0xc2376c84), TOBN(0x8315b659, 0x3d1aa783),
+ TOBN(0x3a75c484, 0xef852a90), TOBN(0x0ba0c58a, 0x16086bd4)}},
+ {{TOBN(0x29688d7a, 0x529a6d48), TOBN(0x9c7f250d, 0xc2f19203),
+ TOBN(0x123042fb, 0x682e2df9), TOBN(0x2b7587e7, 0xad8121bc)},
+ {TOBN(0x30fc0233, 0xe0182a65), TOBN(0xb82ecf87, 0xe3e1128a),
+ TOBN(0x71682861, 0x93fb098f), TOBN(0x043e21ae, 0x85e9e6a7)}},
+ {{TOBN(0xab5b49d6, 0x66c834ea), TOBN(0x3be43e18, 0x47414287),
+ TOBN(0xf40fb859, 0x219a2a47), TOBN(0x0e6559e9, 0xcc58df3c)},
+ {TOBN(0xfe1dfe8e, 0x0c6615b4), TOBN(0x14abc8fd, 0x56459d70),
+ TOBN(0x7be0fa8e, 0x05de0386), TOBN(0x8e63ef68, 0xe9035c7c)}},
+ {{TOBN(0x116401b4, 0x53b31e91), TOBN(0x0cba7ad4, 0x4436b4d8),
+ TOBN(0x9151f9a0, 0x107afd66), TOBN(0xafaca8d0, 0x1f0ee4c4)},
+ {TOBN(0x75fe5c1d, 0x9ee9761c), TOBN(0x3497a16b, 0xf0c0588f),
+ TOBN(0x3ee2bebd, 0x0304804c), TOBN(0xa8fb9a60, 0xc2c990b9)}},
+ {{TOBN(0xd14d32fe, 0x39251114), TOBN(0x36bf25bc, 0xcac73366),
+ TOBN(0xc9562c66, 0xdba7495c), TOBN(0x324d301b, 0x46ad348b)},
+ {TOBN(0x9f46620c, 0xd670407e), TOBN(0x0ea8d4f1, 0xe3733a01),
+ TOBN(0xd396d532, 0xb0c324e0), TOBN(0x5b211a0e, 0x03c317cd)}},
+ {{TOBN(0x090d7d20, 0x5ffe7b37), TOBN(0x3b7f3efb, 0x1747d2da),
+ TOBN(0xa2cb525f, 0xb54fc519), TOBN(0x6e220932, 0xf66a971e)},
+ {TOBN(0xddc160df, 0xb486d440), TOBN(0x7fcfec46, 0x3fe13465),
+ TOBN(0x83da7e4e, 0x76e4c151), TOBN(0xd6fa48a1, 0xd8d302b5)}},
+ {{TOBN(0xc6304f26, 0x5872cd88), TOBN(0x806c1d3c, 0x278b90a1),
+ TOBN(0x3553e725, 0xcaf0bc1c), TOBN(0xff59e603, 0xbb9d8d5c)},
+ {TOBN(0xa4550f32, 0x7a0b85dd), TOBN(0xdec5720a, 0x93ecc217),
+ TOBN(0x0b88b741, 0x69d62213), TOBN(0x7212f245, 0x5b365955)}},
+ {{TOBN(0x20764111, 0xb5cae787), TOBN(0x13cb7f58, 0x1dfd3124),
+ TOBN(0x2dca77da, 0x1175aefb), TOBN(0xeb75466b, 0xffaae775)},
+ {TOBN(0x74d76f3b, 0xdb6cff32), TOBN(0x7440f37a, 0x61fcda9a),
+ TOBN(0x1bb3ac92, 0xb525028b), TOBN(0x20fbf8f7, 0xa1975f29)}},
+ {{TOBN(0x982692e1, 0xdf83097f), TOBN(0x28738f6c, 0x554b0800),
+ TOBN(0xdc703717, 0xa2ce2f2f), TOBN(0x7913b93c, 0x40814194)},
+ {TOBN(0x04924593, 0x1fe89636), TOBN(0x7b98443f, 0xf78834a6),
+ TOBN(0x11c6ab01, 0x5114a5a1), TOBN(0x60deb383, 0xffba5f4c)}},
+ {{TOBN(0x4caa54c6, 0x01a982e6), TOBN(0x1dd35e11, 0x3491cd26),
+ TOBN(0x973c315f, 0x7cbd6b05), TOBN(0xcab00775, 0x52494724)},
+ {TOBN(0x04659b1f, 0x6565e15a), TOBN(0xbf30f529, 0x8c8fb026),
+ TOBN(0xfc21641b, 0xa8a0de37), TOBN(0xe9c7a366, 0xfa5e5114)}},
+ {{TOBN(0xdb849ca5, 0x52f03ad8), TOBN(0xc7e8dbe9, 0x024e35c0),
+ TOBN(0xa1a2bbac, 0xcfc3c789), TOBN(0xbf733e7d, 0x9c26f262)},
+ {TOBN(0x882ffbf5, 0xb8444823), TOBN(0xb7224e88, 0x6bf8483b),
+ TOBN(0x53023b8b, 0x65bef640), TOBN(0xaabfec91, 0xd4d5f8cd)}},
+ {{TOBN(0xa40e1510, 0x079ea1bd), TOBN(0x1ad9addc, 0xd05d5d26),
+ TOBN(0xdb3f2eab, 0x13e68d4f), TOBN(0x1cff1ae2, 0x640f803f)},
+ {TOBN(0xe0e7b749, 0xd4cee117), TOBN(0x8e9f275b, 0x4036d909),
+ TOBN(0xce34e31d, 0x8f4d4c38), TOBN(0x22b37f69, 0xd75130fc)}},
+ {{TOBN(0x83e0f1fd, 0xb4014604), TOBN(0xa8ce9919, 0x89415078),
+ TOBN(0x82375b75, 0x41792efe), TOBN(0x4f59bf5c, 0x97d4515b)},
+ {TOBN(0xac4f324f, 0x923a277d), TOBN(0xd9bc9b7d, 0x650f3406),
+ TOBN(0xc6fa87d1, 0x8a39bc51), TOBN(0x82588530, 0x5ccc108f)}},
+ {{TOBN(0x5ced3c9f, 0x82e4c634), TOBN(0x8efb8314, 0x3a4464f8),
+ TOBN(0xe706381b, 0x7a1dca25), TOBN(0x6cd15a3c, 0x5a2a412b)},
+ {TOBN(0x9347a8fd, 0xbfcd8fb5), TOBN(0x31db2eef, 0x6e54cd22),
+ TOBN(0xc4aeb11e, 0xf8d8932f), TOBN(0x11e7c1ed, 0x344411af)}},
+ {{TOBN(0x2653050c, 0xdc9a151e), TOBN(0x9edbfc08, 0x3bb0a859),
+ TOBN(0x926c81c7, 0xfd5691e7), TOBN(0x9c1b2342, 0x6f39019a)},
+ {TOBN(0x64a81c8b, 0x7f8474b9), TOBN(0x90657c07, 0x01761819),
+ TOBN(0x390b3331, 0x55e0375a), TOBN(0xc676c626, 0xb6ebc47d)}},
+ {{TOBN(0x51623247, 0xb7d6dee8), TOBN(0x0948d927, 0x79659313),
+ TOBN(0x99700161, 0xe9ab35ed), TOBN(0x06cc32b4, 0x8ddde408)},
+ {TOBN(0x6f2fd664, 0x061ef338), TOBN(0x1606fa02, 0xc202e9ed),
+ TOBN(0x55388bc1, 0x929ba99b), TOBN(0xc4428c5e, 0x1e81df69)}},
+ {{TOBN(0xce2028ae, 0xf91b0b2a), TOBN(0xce870a23, 0xf03dfd3f),
+ TOBN(0x66ec2c87, 0x0affe8ed), TOBN(0xb205fb46, 0x284d0c00)},
+ {TOBN(0xbf5dffe7, 0x44cefa48), TOBN(0xb6fc37a8, 0xa19876d7),
+ TOBN(0xbecfa84c, 0x08b72863), TOBN(0xd7205ff5, 0x2576374f)}},
+ {{TOBN(0x80330d32, 0x8887de41), TOBN(0x5de0df0c, 0x869ea534),
+ TOBN(0x13f42753, 0x3c56ea17), TOBN(0xeb1f6069, 0x452b1a78)},
+ {TOBN(0x50474396, 0xe30ea15c), TOBN(0x575816a1, 0xc1494125),
+ TOBN(0xbe1ce55b, 0xfe6bb38f), TOBN(0xb901a948, 0x96ae30f7)}},
+ {{TOBN(0xe5af0f08, 0xd8fc3548), TOBN(0x5010b5d0, 0xd73bfd08),
+ TOBN(0x993d2880, 0x53fe655a), TOBN(0x99f2630b, 0x1c1309fd)},
+ {TOBN(0xd8677baf, 0xb4e3b76f), TOBN(0x14e51ddc, 0xb840784b),
+ TOBN(0x326c750c, 0xbf0092ce), TOBN(0xc83d306b, 0xf528320f)}},
+ {{TOBN(0xc4456715, 0x77d4715c), TOBN(0xd30019f9, 0x6b703235),
+ TOBN(0x207ccb2e, 0xd669e986), TOBN(0x57c824af, 0xf6dbfc28)},
+ {TOBN(0xf0eb532f, 0xd8f92a23), TOBN(0x4a557fd4, 0x9bb98fd2),
+ TOBN(0xa57acea7, 0xc1e6199a), TOBN(0x0c663820, 0x8b94b1ed)}},
+ {{TOBN(0x9b42be8f, 0xf83a9266), TOBN(0xc7741c97, 0x0101bd45),
+ TOBN(0x95770c11, 0x07bd9ceb), TOBN(0x1f50250a, 0x8b2e0744)},
+ {TOBN(0xf762eec8, 0x1477b654), TOBN(0xc65b900e, 0x15efe59a),
+ TOBN(0x88c96148, 0x9546a897), TOBN(0x7e8025b3, 0xc30b4d7c)}},
+ {{TOBN(0xae4065ef, 0x12045cf9), TOBN(0x6fcb2caf, 0x9ccce8bd),
+ TOBN(0x1fa0ba4e, 0xf2cf6525), TOBN(0xf683125d, 0xcb72c312)},
+ {TOBN(0xa01da4ea, 0xe312410e), TOBN(0x67e28677, 0x6cd8e830),
+ TOBN(0xabd95752, 0x98fb3f07), TOBN(0x05f11e11, 0xeef649a5)}},
+ {{TOBN(0xba47faef, 0x9d3472c2), TOBN(0x3adff697, 0xc77d1345),
+ TOBN(0x4761fa04, 0xdd15afee), TOBN(0x64f1f61a, 0xb9e69462)},
+ {TOBN(0xfa691fab, 0x9bfb9093), TOBN(0x3df8ae8f, 0xa1133dfe),
+ TOBN(0xcd5f8967, 0x58cc710d), TOBN(0xfbb88d50, 0x16c7fe79)}},
+ {{TOBN(0x8e011b4c, 0xe88c50d1), TOBN(0x7532e807, 0xa8771c4f),
+ TOBN(0x64c78a48, 0xe2278ee4), TOBN(0x0b283e83, 0x3845072a)},
+ {TOBN(0x98a6f291, 0x49e69274), TOBN(0xb96e9668, 0x1868b21c),
+ TOBN(0x38f0adc2, 0xb1a8908e), TOBN(0x90afcff7, 0x1feb829d)}},
+ {{TOBN(0x9915a383, 0x210b0856), TOBN(0xa5a80602, 0xdef04889),
+ TOBN(0x800e9af9, 0x7c64d509), TOBN(0x81382d0b, 0xb8996f6f)},
+ {TOBN(0x490eba53, 0x81927e27), TOBN(0x46c63b32, 0x4af50182),
+ TOBN(0x784c5fd9, 0xd3ad62ce), TOBN(0xe4fa1870, 0xf8ae8736)}},
+ {{TOBN(0x4ec9d0bc, 0xd7466b25), TOBN(0x84ddbe1a, 0xdb235c65),
+ TOBN(0x5e2645ee, 0x163c1688), TOBN(0x570bd00e, 0x00eba747)},
+ {TOBN(0xfa51b629, 0x128bfa0f), TOBN(0x92fce1bd, 0x6c1d3b68),
+ TOBN(0x3e7361dc, 0xb66778b1), TOBN(0x9c7d249d, 0x5561d2bb)}},
+ {{TOBN(0xa40b28bf, 0x0bbc6229), TOBN(0x1c83c05e, 0xdfd91497),
+ TOBN(0x5f9f5154, 0xf083df05), TOBN(0xbac38b3c, 0xeee66c9d)},
+ {TOBN(0xf71db7e3, 0xec0dfcfd), TOBN(0xf2ecda8e, 0x8b0a8416),
+ TOBN(0x52fddd86, 0x7812aa66), TOBN(0x2896ef10, 0x4e6f4272)}},
+ {{TOBN(0xff27186a, 0x0fe9a745), TOBN(0x08249fcd, 0x49ca70db),
+ TOBN(0x7425a2e6, 0x441cac49), TOBN(0xf4a0885a, 0xece5ff57)},
+ {TOBN(0x6e2cb731, 0x7d7ead58), TOBN(0xf96cf7d6, 0x1898d104),
+ TOBN(0xafe67c9d, 0x4f2c9a89), TOBN(0x89895a50, 0x1c7bf5bc)}},
+ {{TOBN(0xdc7cb8e5, 0x573cecfa), TOBN(0x66497eae, 0xd15f03e6),
+ TOBN(0x6bc0de69, 0x3f084420), TOBN(0x323b9b36, 0xacd532b0)},
+ {TOBN(0xcfed390a, 0x0115a3c1), TOBN(0x9414c40b, 0x2d65ca0e),
+ TOBN(0x641406bd, 0x2f530c78), TOBN(0x29369a44, 0x833438f2)}},
+ {{TOBN(0x996884f5, 0x903fa271), TOBN(0xe6da0fd2, 0xb9da921e),
+ TOBN(0xa6f2f269, 0x5db01e54), TOBN(0x1ee3e9bd, 0x6876214e)},
+ {TOBN(0xa26e181c, 0xe27a9497), TOBN(0x36d254e4, 0x8e215e04),
+ TOBN(0x42f32a6c, 0x252cabca), TOBN(0x99481487, 0x80b57614)}},
+ {{TOBN(0x4c4dfe69, 0x40d9cae1), TOBN(0x05869580, 0x11a10f09),
+ TOBN(0xca287b57, 0x3491b64b), TOBN(0x77862d5d, 0x3fd4a53b)},
+ {TOBN(0xbf94856e, 0x50349126), TOBN(0x2be30bd1, 0x71c5268f),
+ TOBN(0x10393f19, 0xcbb650a6), TOBN(0x639531fe, 0x778cf9fd)}},
+ {{TOBN(0x02556a11, 0xb2935359), TOBN(0xda38aa96, 0xaf8c126e),
+ TOBN(0x47dbe6c2, 0x0960167f), TOBN(0x37bbabb6, 0x501901cd)},
+ {TOBN(0xb6e979e0, 0x2c947778), TOBN(0xd69a5175, 0x7a1a1dc6),
+ TOBN(0xc3ed5095, 0x9d9faf0c), TOBN(0x4dd9c096, 0x1d5fa5f0)}},
+ {{TOBN(0xa0c4304d, 0x64f16ea8), TOBN(0x8b1cac16, 0x7e718623),
+ TOBN(0x0b576546, 0x7c67f03e), TOBN(0x559cf5ad, 0xcbd88c01)},
+ {TOBN(0x074877bb, 0x0e2af19a), TOBN(0x1f717ec1, 0xa1228c92),
+ TOBN(0x70bcb800, 0x326e8920), TOBN(0xec6e2c5c, 0x4f312804)}},
+ {{TOBN(0x426aea7d, 0x3fca4752), TOBN(0xf12c0949, 0x2211f62a),
+ TOBN(0x24beecd8, 0x7be7b6b5), TOBN(0xb77eaf4c, 0x36d7a27d)},
+ {TOBN(0x154c2781, 0xfda78fd3), TOBN(0x848a83b0, 0x264eeabe),
+ TOBN(0x81287ef0, 0x4ffe2bc4), TOBN(0x7b6d88c6, 0xb6b6fc2a)}},
+ {{TOBN(0x805fb947, 0xce417d99), TOBN(0x4b93dcc3, 0x8b916cc4),
+ TOBN(0x72e65bb3, 0x21273323), TOBN(0xbcc1badd, 0x6ea9886e)},
+ {TOBN(0x0e223011, 0x4bc5ee85), TOBN(0xa561be74, 0xc18ee1e4),
+ TOBN(0x762fd2d4, 0xa6bcf1f1), TOBN(0x50e6a5a4, 0x95231489)}},
+ {{TOBN(0xca96001f, 0xa00b500b), TOBN(0x5c098cfc, 0x5d7dcdf5),
+ TOBN(0xa64e2d2e, 0x8c446a85), TOBN(0xbae9bcf1, 0x971f3c62)},
+ {TOBN(0x4ec22683, 0x8435a2c5), TOBN(0x8ceaed6c, 0x4bad4643),
+ TOBN(0xe9f8fb47, 0xccccf4e3), TOBN(0xbd4f3fa4, 0x1ce3b21e)}},
+ {{TOBN(0xd79fb110, 0xa3db3292), TOBN(0xe28a37da, 0xb536c66a),
+ TOBN(0x279ce87b, 0x8e49e6a9), TOBN(0x70ccfe8d, 0xfdcec8e3)},
+ {TOBN(0x2193e4e0, 0x3ba464b2), TOBN(0x0f39d60e, 0xaca9a398),
+ TOBN(0x7d7932af, 0xf82c12ab), TOBN(0xd8ff50ed, 0x91e7e0f7)}},
+ {{TOBN(0xea961058, 0xfa28a7e0), TOBN(0xc726cf25, 0x0bf5ec74),
+ TOBN(0xe74d55c8, 0xdb229666), TOBN(0x0bd9abbf, 0xa57f5799)},
+ {TOBN(0x7479ef07, 0x4dfc47b3), TOBN(0xd9c65fc3, 0x0c52f91d),
+ TOBN(0x8e0283fe, 0x36a8bde2), TOBN(0xa32a8b5e, 0x7d4b7280)}},
+ {{TOBN(0x6a677c61, 0x12e83233), TOBN(0x0fbb3512, 0xdcc9bf28),
+ TOBN(0x562e8ea5, 0x0d780f61), TOBN(0x0db8b22b, 0x1dc4e89c)},
+ {TOBN(0x0a6fd1fb, 0x89be0144), TOBN(0x8c77d246, 0xca57113b),
+ TOBN(0x4639075d, 0xff09c91c), TOBN(0x5b47b17f, 0x5060824c)}},
+ {{TOBN(0x58aea2b0, 0x16287b52), TOBN(0xa1343520, 0xd0cd8eb0),
+ TOBN(0x6148b4d0, 0xc5d58573), TOBN(0xdd2b6170, 0x291c68ae)},
+ {TOBN(0xa61b3929, 0x1da3b3b7), TOBN(0x5f946d79, 0x08c4ac10),
+ TOBN(0x4105d4a5, 0x7217d583), TOBN(0x5061da3d, 0x25e6de5e)}},
+ {{TOBN(0x3113940d, 0xec1b4991), TOBN(0xf12195e1, 0x36f485ae),
+ TOBN(0xa7507fb2, 0x731a2ee0), TOBN(0x95057a8e, 0x6e9e196e)},
+ {TOBN(0xa3c2c911, 0x2e130136), TOBN(0x97dfbb36, 0x33c60d15),
+ TOBN(0xcaf3c581, 0xb300ee2b), TOBN(0x77f25d90, 0xf4bac8b8)}},
+ {{TOBN(0xdb1c4f98, 0x6d840cd6), TOBN(0x471d62c0, 0xe634288c),
+ TOBN(0x8ec2f85e, 0xcec8a161), TOBN(0x41f37cbc, 0xfa6f4ae2)},
+ {TOBN(0x6793a20f, 0x4b709985), TOBN(0x7a7bd33b, 0xefa8985b),
+ TOBN(0x2c6a3fbd, 0x938e6446), TOBN(0x19042619, 0x2a8d47c1)}},
+ {{TOBN(0x16848667, 0xcc36975f), TOBN(0x02acf168, 0x9d5f1dfb),
+ TOBN(0x62d41ad4, 0x613baa94), TOBN(0xb56fbb92, 0x9f684670)},
+ {TOBN(0xce610d0d, 0xe9e40569), TOBN(0x7b99c65f, 0x35489fef),
+ TOBN(0x0c88ad1b, 0x3df18b97), TOBN(0x81b7d9be, 0x5d0e9edb)}},
+ {{TOBN(0xd85218c0, 0xc716cc0a), TOBN(0xf4b5ff90, 0x85691c49),
+ TOBN(0xa4fd666b, 0xce356ac6), TOBN(0x17c72895, 0x4b327a7a)},
+ {TOBN(0xf93d5085, 0xda6be7de), TOBN(0xff71530e, 0x3301d34e),
+ TOBN(0x4cd96442, 0xd8f448e8), TOBN(0x9283d331, 0x2ed18ffa)}},
+ {{TOBN(0x4d33dd99, 0x2a849870), TOBN(0xa716964b, 0x41576335),
+ TOBN(0xff5e3a9b, 0x179be0e5), TOBN(0x5b9d6b1b, 0x83b13632)},
+ {TOBN(0x3b8bd7d4, 0xa52f313b), TOBN(0xc9dd95a0, 0x637a4660),
+ TOBN(0x30035962, 0x0b3e218f), TOBN(0xce1481a3, 0xc7b28a3c)}},
+ {{TOBN(0xab41b43a, 0x43228d83), TOBN(0x24ae1c30, 0x4ad63f99),
+ TOBN(0x8e525f1a, 0x46a51229), TOBN(0x14af860f, 0xcd26d2b4)},
+ {TOBN(0xd6baef61, 0x3f714aa1), TOBN(0xf51865ad, 0xeb78795e),
+ TOBN(0xd3e21fce, 0xe6a9d694), TOBN(0x82ceb1dd, 0x8a37b527)}}}};
diff --git a/src/crypto/fipsmodule/ec/p256-nistz.c b/src/crypto/fipsmodule/ec/p256-nistz.c
new file mode 100644
index 0000000..dfde2f4
--- /dev/null
+++ b/src/crypto/fipsmodule/ec/p256-nistz.c
@@ -0,0 +1,640 @@
+/*
+ * Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright (c) 2014, Intel Corporation. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ *
+ * Originally written by Shay Gueron (1, 2), and Vlad Krasnov (1)
+ * (1) Intel Corporation, Israel Development Center, Haifa, Israel
+ * (2) University of Haifa, Israel
+ *
+ * Reference:
+ * S.Gueron and V.Krasnov, "Fast Prime Field Elliptic Curve Cryptography with
+ * 256 Bit Primes"
+ */
+
+#include <openssl/ec.h>
+
+#include <assert.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <openssl/bn.h>
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+
+#include "../bn/internal.h"
+#include "../delocate.h"
+#include "../../internal.h"
+#include "internal.h"
+#include "p256-nistz.h"
+
+#if !defined(OPENSSL_NO_ASM) && \
+ (defined(OPENSSL_X86_64) || defined(OPENSSL_AARCH64)) && \
+ !defined(OPENSSL_SMALL)
+
+typedef P256_POINT_AFFINE PRECOMP256_ROW[64];
+
+// One converted into the Montgomery domain
+static const BN_ULONG ONE[P256_LIMBS] = {
+ TOBN(0x00000000, 0x00000001), TOBN(0xffffffff, 0x00000000),
+ TOBN(0xffffffff, 0xffffffff), TOBN(0x00000000, 0xfffffffe),
+};
+
+// Precomputed tables for the default generator
+#include "p256-nistz-table.h"
+
+// Recode window to a signed digit, see |ec_GFp_nistp_recode_scalar_bits| in
+// util.c for details
+static crypto_word_t booth_recode_w5(crypto_word_t in) {
+ crypto_word_t s, d;
+
+ s = ~((in >> 5) - 1);
+ d = (1 << 6) - in - 1;
+ d = (d & s) | (in & ~s);
+ d = (d >> 1) + (d & 1);
+
+ return (d << 1) + (s & 1);
+}
+
+static crypto_word_t booth_recode_w7(crypto_word_t in) {
+ crypto_word_t s, d;
+
+ s = ~((in >> 7) - 1);
+ d = (1 << 8) - in - 1;
+ d = (d & s) | (in & ~s);
+ d = (d >> 1) + (d & 1);
+
+ return (d << 1) + (s & 1);
+}
+
+// copy_conditional copies |src| to |dst| if |move| is one and leaves it as-is
+// if |move| is zero.
+//
+// WARNING: this breaks the usual convention of constant-time functions
+// returning masks.
+static void copy_conditional(BN_ULONG dst[P256_LIMBS],
+ const BN_ULONG src[P256_LIMBS], BN_ULONG move) {
+ BN_ULONG mask1 = ((BN_ULONG)0) - move;
+ BN_ULONG mask2 = ~mask1;
+
+ dst[0] = (src[0] & mask1) ^ (dst[0] & mask2);
+ dst[1] = (src[1] & mask1) ^ (dst[1] & mask2);
+ dst[2] = (src[2] & mask1) ^ (dst[2] & mask2);
+ dst[3] = (src[3] & mask1) ^ (dst[3] & mask2);
+ if (P256_LIMBS == 8) {
+ dst[4] = (src[4] & mask1) ^ (dst[4] & mask2);
+ dst[5] = (src[5] & mask1) ^ (dst[5] & mask2);
+ dst[6] = (src[6] & mask1) ^ (dst[6] & mask2);
+ dst[7] = (src[7] & mask1) ^ (dst[7] & mask2);
+ }
+}
+
+// is_not_zero returns one iff in != 0 and zero otherwise.
+//
+// WARNING: this breaks the usual convention of constant-time functions
+// returning masks.
+//
+// (define-fun is_not_zero ((in (_ BitVec 64))) (_ BitVec 64)
+// (bvlshr (bvor in (bvsub #x0000000000000000 in)) #x000000000000003f)
+// )
+//
+// (declare-fun x () (_ BitVec 64))
+//
+// (assert (and (= x #x0000000000000000) (= (is_not_zero x) #x0000000000000001)))
+// (check-sat)
+//
+// (assert (and (not (= x #x0000000000000000)) (= (is_not_zero x) #x0000000000000000)))
+// (check-sat)
+//
+static BN_ULONG is_not_zero(BN_ULONG in) {
+ in |= (0 - in);
+ in >>= BN_BITS2 - 1;
+ return in;
+}
+
+// ecp_nistz256_mod_inverse_sqr_mont sets |r| to (|in| * 2^-256)^-2 * 2^256 mod
+// p. That is, |r| is the modular inverse square of |in| for input and output in
+// the Montgomery domain.
+static void ecp_nistz256_mod_inverse_sqr_mont(BN_ULONG r[P256_LIMBS],
+ const BN_ULONG in[P256_LIMBS]) {
+ // This implements the addition chain described in
+ // https://briansmith.org/ecc-inversion-addition-chains-01#p256_field_inversion
+ BN_ULONG x2[P256_LIMBS], x3[P256_LIMBS], x6[P256_LIMBS], x12[P256_LIMBS],
+ x15[P256_LIMBS], x30[P256_LIMBS], x32[P256_LIMBS];
+ ecp_nistz256_sqr_mont(x2, in); // 2^2 - 2^1
+ ecp_nistz256_mul_mont(x2, x2, in); // 2^2 - 2^0
+
+ ecp_nistz256_sqr_mont(x3, x2); // 2^3 - 2^1
+ ecp_nistz256_mul_mont(x3, x3, in); // 2^3 - 2^0
+
+ ecp_nistz256_sqr_mont(x6, x3);
+ for (int i = 1; i < 3; i++) {
+ ecp_nistz256_sqr_mont(x6, x6);
+ } // 2^6 - 2^3
+ ecp_nistz256_mul_mont(x6, x6, x3); // 2^6 - 2^0
+
+ ecp_nistz256_sqr_mont(x12, x6);
+ for (int i = 1; i < 6; i++) {
+ ecp_nistz256_sqr_mont(x12, x12);
+ } // 2^12 - 2^6
+ ecp_nistz256_mul_mont(x12, x12, x6); // 2^12 - 2^0
+
+ ecp_nistz256_sqr_mont(x15, x12);
+ for (int i = 1; i < 3; i++) {
+ ecp_nistz256_sqr_mont(x15, x15);
+ } // 2^15 - 2^3
+ ecp_nistz256_mul_mont(x15, x15, x3); // 2^15 - 2^0
+
+ ecp_nistz256_sqr_mont(x30, x15);
+ for (int i = 1; i < 15; i++) {
+ ecp_nistz256_sqr_mont(x30, x30);
+ } // 2^30 - 2^15
+ ecp_nistz256_mul_mont(x30, x30, x15); // 2^30 - 2^0
+
+ ecp_nistz256_sqr_mont(x32, x30);
+ ecp_nistz256_sqr_mont(x32, x32); // 2^32 - 2^2
+ ecp_nistz256_mul_mont(x32, x32, x2); // 2^32 - 2^0
+
+ BN_ULONG ret[P256_LIMBS];
+ ecp_nistz256_sqr_mont(ret, x32);
+ for (int i = 1; i < 31 + 1; i++) {
+ ecp_nistz256_sqr_mont(ret, ret);
+ } // 2^64 - 2^32
+ ecp_nistz256_mul_mont(ret, ret, in); // 2^64 - 2^32 + 2^0
+
+ for (int i = 0; i < 96 + 32; i++) {
+ ecp_nistz256_sqr_mont(ret, ret);
+ } // 2^192 - 2^160 + 2^128
+ ecp_nistz256_mul_mont(ret, ret, x32); // 2^192 - 2^160 + 2^128 + 2^32 - 2^0
+
+ for (int i = 0; i < 32; i++) {
+ ecp_nistz256_sqr_mont(ret, ret);
+ } // 2^224 - 2^192 + 2^160 + 2^64 - 2^32
+ ecp_nistz256_mul_mont(ret, ret, x32); // 2^224 - 2^192 + 2^160 + 2^64 - 2^0
+
+ for (int i = 0; i < 30; i++) {
+ ecp_nistz256_sqr_mont(ret, ret);
+ } // 2^254 - 2^222 + 2^190 + 2^94 - 2^30
+ ecp_nistz256_mul_mont(ret, ret, x30); // 2^254 - 2^222 + 2^190 + 2^94 - 2^0
+
+ ecp_nistz256_sqr_mont(ret, ret);
+ ecp_nistz256_sqr_mont(r, ret); // 2^256 - 2^224 + 2^192 + 2^96 - 2^2
+}
+
+// r = p * p_scalar
+static void ecp_nistz256_windowed_mul(const EC_GROUP *group, P256_POINT *r,
+ const EC_JACOBIAN *p,
+ const EC_SCALAR *p_scalar) {
+ assert(p != NULL);
+ assert(p_scalar != NULL);
+ assert(group->field.width == P256_LIMBS);
+
+ static const size_t kWindowSize = 5;
+ static const crypto_word_t kMask = (1 << (5 /* kWindowSize */ + 1)) - 1;
+
+ // A |P256_POINT| is (3 * 32) = 96 bytes, and the 64-byte alignment should
+ // add no more than 63 bytes of overhead. Thus, |table| should require
+ // ~1599 ((96 * 16) + 63) bytes of stack space.
+ alignas(64) P256_POINT table[16];
+ uint8_t p_str[33];
+ OPENSSL_memcpy(p_str, p_scalar->words, 32);
+ p_str[32] = 0;
+
+ // table[0] is implicitly (0,0,0) (the point at infinity), therefore it is
+ // not stored. All other values are actually stored with an offset of -1 in
+ // table.
+ P256_POINT *row = table;
+ assert(group->field.width == P256_LIMBS);
+ OPENSSL_memcpy(row[1 - 1].X, p->X.words, P256_LIMBS * sizeof(BN_ULONG));
+ OPENSSL_memcpy(row[1 - 1].Y, p->Y.words, P256_LIMBS * sizeof(BN_ULONG));
+ OPENSSL_memcpy(row[1 - 1].Z, p->Z.words, P256_LIMBS * sizeof(BN_ULONG));
+
+ ecp_nistz256_point_double(&row[2 - 1], &row[1 - 1]);
+ ecp_nistz256_point_add(&row[3 - 1], &row[2 - 1], &row[1 - 1]);
+ ecp_nistz256_point_double(&row[4 - 1], &row[2 - 1]);
+ ecp_nistz256_point_double(&row[6 - 1], &row[3 - 1]);
+ ecp_nistz256_point_double(&row[8 - 1], &row[4 - 1]);
+ ecp_nistz256_point_double(&row[12 - 1], &row[6 - 1]);
+ ecp_nistz256_point_add(&row[5 - 1], &row[4 - 1], &row[1 - 1]);
+ ecp_nistz256_point_add(&row[7 - 1], &row[6 - 1], &row[1 - 1]);
+ ecp_nistz256_point_add(&row[9 - 1], &row[8 - 1], &row[1 - 1]);
+ ecp_nistz256_point_add(&row[13 - 1], &row[12 - 1], &row[1 - 1]);
+ ecp_nistz256_point_double(&row[14 - 1], &row[7 - 1]);
+ ecp_nistz256_point_double(&row[10 - 1], &row[5 - 1]);
+ ecp_nistz256_point_add(&row[15 - 1], &row[14 - 1], &row[1 - 1]);
+ ecp_nistz256_point_add(&row[11 - 1], &row[10 - 1], &row[1 - 1]);
+ ecp_nistz256_point_double(&row[16 - 1], &row[8 - 1]);
+
+ BN_ULONG tmp[P256_LIMBS];
+ alignas(32) P256_POINT h;
+ size_t index = 255;
+ crypto_word_t wvalue = p_str[(index - 1) / 8];
+ wvalue = (wvalue >> ((index - 1) % 8)) & kMask;
+
+ ecp_nistz256_select_w5(r, table, booth_recode_w5(wvalue) >> 1);
+
+ while (index >= 5) {
+ if (index != 255) {
+ size_t off = (index - 1) / 8;
+
+ wvalue = (crypto_word_t)p_str[off] | (crypto_word_t)p_str[off + 1] << 8;
+ wvalue = (wvalue >> ((index - 1) % 8)) & kMask;
+
+ wvalue = booth_recode_w5(wvalue);
+
+ ecp_nistz256_select_w5(&h, table, wvalue >> 1);
+
+ ecp_nistz256_neg(tmp, h.Y);
+ copy_conditional(h.Y, tmp, (wvalue & 1));
+
+ ecp_nistz256_point_add(r, r, &h);
+ }
+
+ index -= kWindowSize;
+
+ ecp_nistz256_point_double(r, r);
+ ecp_nistz256_point_double(r, r);
+ ecp_nistz256_point_double(r, r);
+ ecp_nistz256_point_double(r, r);
+ ecp_nistz256_point_double(r, r);
+ }
+
+ // Final window
+ wvalue = p_str[0];
+ wvalue = (wvalue << 1) & kMask;
+
+ wvalue = booth_recode_w5(wvalue);
+
+ ecp_nistz256_select_w5(&h, table, wvalue >> 1);
+
+ ecp_nistz256_neg(tmp, h.Y);
+ copy_conditional(h.Y, tmp, wvalue & 1);
+
+ ecp_nistz256_point_add(r, r, &h);
+}
+
+static crypto_word_t calc_first_wvalue(size_t *index, const uint8_t p_str[33]) {
+ static const size_t kWindowSize = 7;
+ static const crypto_word_t kMask = (1 << (7 /* kWindowSize */ + 1)) - 1;
+ *index = kWindowSize;
+
+ crypto_word_t wvalue = (p_str[0] << 1) & kMask;
+ return booth_recode_w7(wvalue);
+}
+
+static crypto_word_t calc_wvalue(size_t *index, const uint8_t p_str[33]) {
+ static const size_t kWindowSize = 7;
+ static const crypto_word_t kMask = (1 << (7 /* kWindowSize */ + 1)) - 1;
+
+ const size_t off = (*index - 1) / 8;
+ crypto_word_t wvalue =
+ (crypto_word_t)p_str[off] | (crypto_word_t)p_str[off + 1] << 8;
+ wvalue = (wvalue >> ((*index - 1) % 8)) & kMask;
+ *index += kWindowSize;
+
+ return booth_recode_w7(wvalue);
+}
+
+static void ecp_nistz256_point_mul(const EC_GROUP *group, EC_JACOBIAN *r,
+ const EC_JACOBIAN *p,
+ const EC_SCALAR *scalar) {
+ alignas(32) P256_POINT out;
+ ecp_nistz256_windowed_mul(group, &out, p, scalar);
+
+ assert(group->field.width == P256_LIMBS);
+ OPENSSL_memcpy(r->X.words, out.X, P256_LIMBS * sizeof(BN_ULONG));
+ OPENSSL_memcpy(r->Y.words, out.Y, P256_LIMBS * sizeof(BN_ULONG));
+ OPENSSL_memcpy(r->Z.words, out.Z, P256_LIMBS * sizeof(BN_ULONG));
+}
+
+static void ecp_nistz256_point_mul_base(const EC_GROUP *group, EC_JACOBIAN *r,
+ const EC_SCALAR *scalar) {
+ uint8_t p_str[33];
+ OPENSSL_memcpy(p_str, scalar->words, 32);
+ p_str[32] = 0;
+
+ // First window
+ size_t index = 0;
+ crypto_word_t wvalue = calc_first_wvalue(&index, p_str);
+
+ alignas(32) P256_POINT_AFFINE t;
+ alignas(32) P256_POINT p;
+ ecp_nistz256_select_w7(&t, ecp_nistz256_precomputed[0], wvalue >> 1);
+ ecp_nistz256_neg(p.Z, t.Y);
+ copy_conditional(t.Y, p.Z, wvalue & 1);
+
+ // Convert |t| from affine to Jacobian coordinates. We set Z to zero if |t|
+ // is infinity and |ONE| otherwise. |t| was computed from the table, so it
+ // is infinity iff |wvalue >> 1| is zero.
+ OPENSSL_memcpy(p.X, t.X, sizeof(p.X));
+ OPENSSL_memcpy(p.Y, t.Y, sizeof(p.Y));
+ OPENSSL_memset(p.Z, 0, sizeof(p.Z));
+ copy_conditional(p.Z, ONE, is_not_zero(wvalue >> 1));
+
+ for (int i = 1; i < 37; i++) {
+ wvalue = calc_wvalue(&index, p_str);
+
+ ecp_nistz256_select_w7(&t, ecp_nistz256_precomputed[i], wvalue >> 1);
+
+ alignas(32) BN_ULONG neg_Y[P256_LIMBS];
+ ecp_nistz256_neg(neg_Y, t.Y);
+ copy_conditional(t.Y, neg_Y, wvalue & 1);
+
+ // Note |ecp_nistz256_point_add_affine| does not work if |p| and |t| are the
+ // same non-infinity point.
+ ecp_nistz256_point_add_affine(&p, &p, &t);
+ }
+
+ assert(group->field.width == P256_LIMBS);
+ OPENSSL_memcpy(r->X.words, p.X, P256_LIMBS * sizeof(BN_ULONG));
+ OPENSSL_memcpy(r->Y.words, p.Y, P256_LIMBS * sizeof(BN_ULONG));
+ OPENSSL_memcpy(r->Z.words, p.Z, P256_LIMBS * sizeof(BN_ULONG));
+}
+
+static void ecp_nistz256_points_mul_public(const EC_GROUP *group,
+ EC_JACOBIAN *r,
+ const EC_SCALAR *g_scalar,
+ const EC_JACOBIAN *p_,
+ const EC_SCALAR *p_scalar) {
+ assert(p_ != NULL && p_scalar != NULL && g_scalar != NULL);
+
+ alignas(32) P256_POINT p;
+ uint8_t p_str[33];
+ OPENSSL_memcpy(p_str, g_scalar->words, 32);
+ p_str[32] = 0;
+
+ // First window
+ size_t index = 0;
+ size_t wvalue = calc_first_wvalue(&index, p_str);
+
+ // Convert |p| from affine to Jacobian coordinates. We set Z to zero if |p|
+ // is infinity and |ONE| otherwise. |p| was computed from the table, so it
+ // is infinity iff |wvalue >> 1| is zero.
+ if ((wvalue >> 1) != 0) {
+ OPENSSL_memcpy(p.X, &ecp_nistz256_precomputed[0][(wvalue >> 1) - 1].X,
+ sizeof(p.X));
+ OPENSSL_memcpy(p.Y, &ecp_nistz256_precomputed[0][(wvalue >> 1) - 1].Y,
+ sizeof(p.Y));
+ OPENSSL_memcpy(p.Z, ONE, sizeof(p.Z));
+ } else {
+ OPENSSL_memset(p.X, 0, sizeof(p.X));
+ OPENSSL_memset(p.Y, 0, sizeof(p.Y));
+ OPENSSL_memset(p.Z, 0, sizeof(p.Z));
+ }
+
+ if ((wvalue & 1) == 1) {
+ ecp_nistz256_neg(p.Y, p.Y);
+ }
+
+ for (int i = 1; i < 37; i++) {
+ wvalue = calc_wvalue(&index, p_str);
+ if ((wvalue >> 1) == 0) {
+ continue;
+ }
+
+ alignas(32) P256_POINT_AFFINE t;
+ OPENSSL_memcpy(&t, &ecp_nistz256_precomputed[i][(wvalue >> 1) - 1],
+ sizeof(t));
+ if ((wvalue & 1) == 1) {
+ ecp_nistz256_neg(t.Y, t.Y);
+ }
+
+ // Note |ecp_nistz256_point_add_affine| does not work if |p| and |t| are
+ // the same non-infinity point, so it is important that we compute the
+ // |g_scalar| term before the |p_scalar| term.
+ ecp_nistz256_point_add_affine(&p, &p, &t);
+ }
+
+ alignas(32) P256_POINT tmp;
+ ecp_nistz256_windowed_mul(group, &tmp, p_, p_scalar);
+ ecp_nistz256_point_add(&p, &p, &tmp);
+
+ assert(group->field.width == P256_LIMBS);
+ OPENSSL_memcpy(r->X.words, p.X, P256_LIMBS * sizeof(BN_ULONG));
+ OPENSSL_memcpy(r->Y.words, p.Y, P256_LIMBS * sizeof(BN_ULONG));
+ OPENSSL_memcpy(r->Z.words, p.Z, P256_LIMBS * sizeof(BN_ULONG));
+}
+
+static int ecp_nistz256_get_affine(const EC_GROUP *group,
+ const EC_JACOBIAN *point, EC_FELEM *x,
+ EC_FELEM *y) {
+ if (ec_GFp_simple_is_at_infinity(group, point)) {
+ OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY);
+ return 0;
+ }
+
+ BN_ULONG z_inv2[P256_LIMBS];
+ assert(group->field.width == P256_LIMBS);
+ ecp_nistz256_mod_inverse_sqr_mont(z_inv2, point->Z.words);
+
+ if (x != NULL) {
+ ecp_nistz256_mul_mont(x->words, z_inv2, point->X.words);
+ }
+
+ if (y != NULL) {
+ ecp_nistz256_sqr_mont(z_inv2, z_inv2); // z^-4
+ ecp_nistz256_mul_mont(y->words, point->Y.words, point->Z.words); // y * z
+ ecp_nistz256_mul_mont(y->words, y->words, z_inv2); // y * z^-3
+ }
+
+ return 1;
+}
+
+static void ecp_nistz256_add(const EC_GROUP *group, EC_JACOBIAN *r,
+ const EC_JACOBIAN *a_, const EC_JACOBIAN *b_) {
+ P256_POINT a, b;
+ OPENSSL_memcpy(a.X, a_->X.words, P256_LIMBS * sizeof(BN_ULONG));
+ OPENSSL_memcpy(a.Y, a_->Y.words, P256_LIMBS * sizeof(BN_ULONG));
+ OPENSSL_memcpy(a.Z, a_->Z.words, P256_LIMBS * sizeof(BN_ULONG));
+ OPENSSL_memcpy(b.X, b_->X.words, P256_LIMBS * sizeof(BN_ULONG));
+ OPENSSL_memcpy(b.Y, b_->Y.words, P256_LIMBS * sizeof(BN_ULONG));
+ OPENSSL_memcpy(b.Z, b_->Z.words, P256_LIMBS * sizeof(BN_ULONG));
+ ecp_nistz256_point_add(&a, &a, &b);
+ OPENSSL_memcpy(r->X.words, a.X, P256_LIMBS * sizeof(BN_ULONG));
+ OPENSSL_memcpy(r->Y.words, a.Y, P256_LIMBS * sizeof(BN_ULONG));
+ OPENSSL_memcpy(r->Z.words, a.Z, P256_LIMBS * sizeof(BN_ULONG));
+}
+
+static void ecp_nistz256_dbl(const EC_GROUP *group, EC_JACOBIAN *r,
+ const EC_JACOBIAN *a_) {
+ P256_POINT a;
+ OPENSSL_memcpy(a.X, a_->X.words, P256_LIMBS * sizeof(BN_ULONG));
+ OPENSSL_memcpy(a.Y, a_->Y.words, P256_LIMBS * sizeof(BN_ULONG));
+ OPENSSL_memcpy(a.Z, a_->Z.words, P256_LIMBS * sizeof(BN_ULONG));
+ ecp_nistz256_point_double(&a, &a);
+ OPENSSL_memcpy(r->X.words, a.X, P256_LIMBS * sizeof(BN_ULONG));
+ OPENSSL_memcpy(r->Y.words, a.Y, P256_LIMBS * sizeof(BN_ULONG));
+ OPENSSL_memcpy(r->Z.words, a.Z, P256_LIMBS * sizeof(BN_ULONG));
+}
+
+static void ecp_nistz256_inv0_mod_ord(const EC_GROUP *group, EC_SCALAR *out,
+ const EC_SCALAR *in) {
+ // table[i] stores a power of |in| corresponding to the matching enum value.
+ enum {
+ // The following indices specify the power in binary.
+ i_1 = 0,
+ i_10,
+ i_11,
+ i_101,
+ i_111,
+ i_1010,
+ i_1111,
+ i_10101,
+ i_101010,
+ i_101111,
+ // The following indices specify 2^N-1, or N ones in a row.
+ i_x6,
+ i_x8,
+ i_x16,
+ i_x32
+ };
+ BN_ULONG table[15][P256_LIMBS];
+
+ // https://briansmith.org/ecc-inversion-addition-chains-01#p256_scalar_inversion
+ //
+ // Even though this code path spares 12 squarings, 4.5%, and 13
+ // multiplications, 25%, the overall sign operation is not that much faster,
+ // not more that 2%. Most of the performance of this function comes from the
+ // scalar operations.
+
+ // Pre-calculate powers.
+ OPENSSL_memcpy(table[i_1], in->words, P256_LIMBS * sizeof(BN_ULONG));
+
+ ecp_nistz256_ord_sqr_mont(table[i_10], table[i_1], 1);
+
+ ecp_nistz256_ord_mul_mont(table[i_11], table[i_1], table[i_10]);
+
+ ecp_nistz256_ord_mul_mont(table[i_101], table[i_11], table[i_10]);
+
+ ecp_nistz256_ord_mul_mont(table[i_111], table[i_101], table[i_10]);
+
+ ecp_nistz256_ord_sqr_mont(table[i_1010], table[i_101], 1);
+
+ ecp_nistz256_ord_mul_mont(table[i_1111], table[i_1010], table[i_101]);
+
+ ecp_nistz256_ord_sqr_mont(table[i_10101], table[i_1010], 1);
+ ecp_nistz256_ord_mul_mont(table[i_10101], table[i_10101], table[i_1]);
+
+ ecp_nistz256_ord_sqr_mont(table[i_101010], table[i_10101], 1);
+
+ ecp_nistz256_ord_mul_mont(table[i_101111], table[i_101010], table[i_101]);
+
+ ecp_nistz256_ord_mul_mont(table[i_x6], table[i_101010], table[i_10101]);
+
+ ecp_nistz256_ord_sqr_mont(table[i_x8], table[i_x6], 2);
+ ecp_nistz256_ord_mul_mont(table[i_x8], table[i_x8], table[i_11]);
+
+ ecp_nistz256_ord_sqr_mont(table[i_x16], table[i_x8], 8);
+ ecp_nistz256_ord_mul_mont(table[i_x16], table[i_x16], table[i_x8]);
+
+ ecp_nistz256_ord_sqr_mont(table[i_x32], table[i_x16], 16);
+ ecp_nistz256_ord_mul_mont(table[i_x32], table[i_x32], table[i_x16]);
+
+ // Compute |in| raised to the order-2.
+ ecp_nistz256_ord_sqr_mont(out->words, table[i_x32], 64);
+ ecp_nistz256_ord_mul_mont(out->words, out->words, table[i_x32]);
+ static const struct {
+ uint8_t p, i;
+ } kChain[27] = {{32, i_x32}, {6, i_101111}, {5, i_111}, {4, i_11},
+ {5, i_1111}, {5, i_10101}, {4, i_101}, {3, i_101},
+ {3, i_101}, {5, i_111}, {9, i_101111}, {6, i_1111},
+ {2, i_1}, {5, i_1}, {6, i_1111}, {5, i_111},
+ {4, i_111}, {5, i_111}, {5, i_101}, {3, i_11},
+ {10, i_101111}, {2, i_11}, {5, i_11}, {5, i_11},
+ {3, i_1}, {7, i_10101}, {6, i_1111}};
+ for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kChain); i++) {
+ ecp_nistz256_ord_sqr_mont(out->words, out->words, kChain[i].p);
+ ecp_nistz256_ord_mul_mont(out->words, out->words, table[kChain[i].i]);
+ }
+}
+
+static int ecp_nistz256_scalar_to_montgomery_inv_vartime(const EC_GROUP *group,
+ EC_SCALAR *out,
+ const EC_SCALAR *in) {
+#if defined(OPENSSL_X86_64)
+ if (!CRYPTO_is_AVX_capable()) {
+ // No AVX support; fallback to generic code.
+ return ec_simple_scalar_to_montgomery_inv_vartime(group, out, in);
+ }
+#endif
+
+ assert(group->order.width == P256_LIMBS);
+ if (!beeu_mod_inverse_vartime(out->words, in->words, group->order.d)) {
+ return 0;
+ }
+
+ // The result should be returned in the Montgomery domain.
+ ec_scalar_to_montgomery(group, out, out);
+ return 1;
+}
+
+static int ecp_nistz256_cmp_x_coordinate(const EC_GROUP *group,
+ const EC_JACOBIAN *p,
+ const EC_SCALAR *r) {
+ if (ec_GFp_simple_is_at_infinity(group, p)) {
+ return 0;
+ }
+
+ assert(group->order.width == P256_LIMBS);
+ assert(group->field.width == P256_LIMBS);
+
+ // We wish to compare X/Z^2 with r. This is equivalent to comparing X with
+ // r*Z^2. Note that X and Z are represented in Montgomery form, while r is
+ // not.
+ BN_ULONG r_Z2[P256_LIMBS], Z2_mont[P256_LIMBS], X[P256_LIMBS];
+ ecp_nistz256_mul_mont(Z2_mont, p->Z.words, p->Z.words);
+ ecp_nistz256_mul_mont(r_Z2, r->words, Z2_mont);
+ ecp_nistz256_from_mont(X, p->X.words);
+
+ if (OPENSSL_memcmp(r_Z2, X, sizeof(r_Z2)) == 0) {
+ return 1;
+ }
+
+ // During signing the x coefficient is reduced modulo the group order.
+ // Therefore there is a small possibility, less than 1/2^128, that group_order
+ // < p.x < P. in that case we need not only to compare against |r| but also to
+ // compare against r+group_order.
+ if (bn_less_than_words(r->words, group->field_minus_order.words,
+ P256_LIMBS)) {
+ // We can ignore the carry because: r + group_order < p < 2^256.
+ bn_add_words(r_Z2, r->words, group->order.d, P256_LIMBS);
+ ecp_nistz256_mul_mont(r_Z2, r_Z2, Z2_mont);
+ if (OPENSSL_memcmp(r_Z2, X, sizeof(r_Z2)) == 0) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+DEFINE_METHOD_FUNCTION(EC_METHOD, EC_GFp_nistz256_method) {
+ out->group_init = ec_GFp_mont_group_init;
+ out->group_finish = ec_GFp_mont_group_finish;
+ out->group_set_curve = ec_GFp_mont_group_set_curve;
+ out->point_get_affine_coordinates = ecp_nistz256_get_affine;
+ out->add = ecp_nistz256_add;
+ out->dbl = ecp_nistz256_dbl;
+ out->mul = ecp_nistz256_point_mul;
+ out->mul_base = ecp_nistz256_point_mul_base;
+ out->mul_public = ecp_nistz256_points_mul_public;
+ out->felem_mul = ec_GFp_mont_felem_mul;
+ out->felem_sqr = ec_GFp_mont_felem_sqr;
+ out->felem_to_bytes = ec_GFp_mont_felem_to_bytes;
+ out->felem_from_bytes = ec_GFp_mont_felem_from_bytes;
+ out->felem_reduce = ec_GFp_mont_felem_reduce;
+ // TODO(davidben): This should use the specialized field arithmetic
+ // implementation, rather than the generic one.
+ out->felem_exp = ec_GFp_mont_felem_exp;
+ out->scalar_inv0_montgomery = ecp_nistz256_inv0_mod_ord;
+ out->scalar_to_montgomery_inv_vartime =
+ ecp_nistz256_scalar_to_montgomery_inv_vartime;
+ out->cmp_x_coordinate = ecp_nistz256_cmp_x_coordinate;
+}
+
+#endif /* !defined(OPENSSL_NO_ASM) && \
+ (defined(OPENSSL_X86_64) || defined(OPENSSL_AARCH64)) && \
+ !defined(OPENSSL_SMALL) */
diff --git a/src/crypto/fipsmodule/ec/p256-nistz.h b/src/crypto/fipsmodule/ec/p256-nistz.h
new file mode 100644
index 0000000..3f5ea02
--- /dev/null
+++ b/src/crypto/fipsmodule/ec/p256-nistz.h
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright (c) 2014, Intel Corporation. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ *
+ * Originally written by Shay Gueron (1, 2), and Vlad Krasnov (1)
+ * (1) Intel Corporation, Israel Development Center, Haifa, Israel
+ * (2) University of Haifa, Israel
+ *
+ * Reference:
+ * S.Gueron and V.Krasnov, "Fast Prime Field Elliptic Curve Cryptography with
+ * 256 Bit Primes"
+ */
+
+#ifndef OPENSSL_HEADER_EC_P256_X86_64_H
+#define OPENSSL_HEADER_EC_P256_X86_64_H
+
+#include <openssl/base.h>
+
+#include <openssl/bn.h>
+
+#include "../bn/internal.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+#if !defined(OPENSSL_NO_ASM) && \
+ (defined(OPENSSL_X86_64) || defined(OPENSSL_AARCH64)) && \
+ !defined(OPENSSL_SMALL)
+
+// P-256 field operations.
+//
+// An element mod P in P-256 is represented as a little-endian array of
+// |P256_LIMBS| |BN_ULONG|s, spanning the full range of values.
+//
+// The following functions take fully-reduced inputs mod P and give
+// fully-reduced outputs. They may be used in-place.
+
+#define P256_LIMBS (256 / BN_BITS2)
+
+// ecp_nistz256_neg sets |res| to -|a| mod P.
+void ecp_nistz256_neg(BN_ULONG res[P256_LIMBS], const BN_ULONG a[P256_LIMBS]);
+
+// ecp_nistz256_mul_mont sets |res| to |a| * |b| * 2^-256 mod P.
+void ecp_nistz256_mul_mont(BN_ULONG res[P256_LIMBS],
+ const BN_ULONG a[P256_LIMBS],
+ const BN_ULONG b[P256_LIMBS]);
+
+// ecp_nistz256_sqr_mont sets |res| to |a| * |a| * 2^-256 mod P.
+void ecp_nistz256_sqr_mont(BN_ULONG res[P256_LIMBS],
+ const BN_ULONG a[P256_LIMBS]);
+
+// ecp_nistz256_from_mont sets |res| to |in|, converted from Montgomery domain
+// by multiplying with 1.
+static inline void ecp_nistz256_from_mont(BN_ULONG res[P256_LIMBS],
+ const BN_ULONG in[P256_LIMBS]) {
+ static const BN_ULONG ONE[P256_LIMBS] = { 1 };
+ ecp_nistz256_mul_mont(res, in, ONE);
+}
+
+
+// P-256 scalar operations.
+//
+// The following functions compute modulo N, where N is the order of P-256. They
+// take fully-reduced inputs and give fully-reduced outputs.
+
+// ecp_nistz256_ord_mul_mont sets |res| to |a| * |b| where inputs and outputs
+// are in Montgomery form. That is, |res| is |a| * |b| * 2^-256 mod N.
+void ecp_nistz256_ord_mul_mont(BN_ULONG res[P256_LIMBS],
+ const BN_ULONG a[P256_LIMBS],
+ const BN_ULONG b[P256_LIMBS]);
+
+// ecp_nistz256_ord_sqr_mont sets |res| to |a|^(2*|rep|) where inputs and
+// outputs are in Montgomery form. That is, |res| is
+// (|a| * 2^-256)^(2*|rep|) * 2^256 mod N.
+void ecp_nistz256_ord_sqr_mont(BN_ULONG res[P256_LIMBS],
+ const BN_ULONG a[P256_LIMBS], BN_ULONG rep);
+
+// beeu_mod_inverse_vartime sets out = a^-1 mod p using a Euclidean algorithm.
+// Assumption: 0 < a < p < 2^(256) and p is odd.
+int beeu_mod_inverse_vartime(BN_ULONG out[P256_LIMBS],
+ const BN_ULONG a[P256_LIMBS],
+ const BN_ULONG p[P256_LIMBS]);
+
+
+// P-256 point operations.
+//
+// The following functions may be used in-place. All coordinates are in the
+// Montgomery domain.
+
+// A P256_POINT represents a P-256 point in Jacobian coordinates.
+typedef struct {
+ BN_ULONG X[P256_LIMBS];
+ BN_ULONG Y[P256_LIMBS];
+ BN_ULONG Z[P256_LIMBS];
+} P256_POINT;
+
+// A P256_POINT_AFFINE represents a P-256 point in affine coordinates. Infinity
+// is encoded as (0, 0).
+typedef struct {
+ BN_ULONG X[P256_LIMBS];
+ BN_ULONG Y[P256_LIMBS];
+} P256_POINT_AFFINE;
+
+// ecp_nistz256_select_w5 sets |*val| to |in_t[index-1]| if 1 <= |index| <= 16
+// and all zeros (the point at infinity) if |index| is 0. This is done in
+// constant time.
+void ecp_nistz256_select_w5(P256_POINT *val, const P256_POINT in_t[16],
+ int index);
+
+// ecp_nistz256_select_w7 sets |*val| to |in_t[index-1]| if 1 <= |index| <= 64
+// and all zeros (the point at infinity) if |index| is 0. This is done in
+// constant time.
+void ecp_nistz256_select_w7(P256_POINT_AFFINE *val,
+ const P256_POINT_AFFINE in_t[64], int index);
+
+// ecp_nistz256_point_double sets |r| to |a| doubled.
+void ecp_nistz256_point_double(P256_POINT *r, const P256_POINT *a);
+
+// ecp_nistz256_point_add adds |a| to |b| and places the result in |r|.
+void ecp_nistz256_point_add(P256_POINT *r, const P256_POINT *a,
+ const P256_POINT *b);
+
+// ecp_nistz256_point_add_affine adds |a| to |b| and places the result in
+// |r|. |a| and |b| must not represent the same point unless they are both
+// infinity.
+void ecp_nistz256_point_add_affine(P256_POINT *r, const P256_POINT *a,
+ const P256_POINT_AFFINE *b);
+
+#endif /* !defined(OPENSSL_NO_ASM) && \
+ (defined(OPENSSL_X86_64) || defined(OPENSSL_AARCH64)) && \
+ !defined(OPENSSL_SMALL) */
+
+
+#if defined(__cplusplus)
+} // extern C++
+#endif
+
+#endif // OPENSSL_HEADER_EC_P256_X86_64_H
diff --git a/src/crypto/fipsmodule/ec/p256-nistz_test.cc b/src/crypto/fipsmodule/ec/p256-nistz_test.cc
new file mode 100644
index 0000000..a53d94e
--- /dev/null
+++ b/src/crypto/fipsmodule/ec/p256-nistz_test.cc
@@ -0,0 +1,582 @@
+/* Copyright (c) 2016, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <openssl/base.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include <gtest/gtest.h>
+
+#include <openssl/bn.h>
+#include <openssl/ec.h>
+#include <openssl/mem.h>
+#include <openssl/nid.h>
+
+#include "internal.h"
+#include "../bn/internal.h"
+#include "../../internal.h"
+#include "../../test/abi_test.h"
+#include "../../test/file_test.h"
+#include "../../test/test_util.h"
+#include "p256-nistz.h"
+
+
+// Disable tests if BORINGSSL_SHARED_LIBRARY is defined. These tests need access
+// to internal functions.
+#if !defined(OPENSSL_NO_ASM) && \
+ (defined(OPENSSL_X86_64) || defined(OPENSSL_AARCH64)) && \
+ !defined(OPENSSL_SMALL) && !defined(BORINGSSL_SHARED_LIBRARY)
+
+TEST(P256_NistzTest, SelectW5) {
+ // Fill a table with some garbage input.
+ alignas(64) P256_POINT table[16];
+ for (size_t i = 0; i < 16; i++) {
+ OPENSSL_memset(table[i].X, static_cast<uint8_t>(3 * i), sizeof(table[i].X));
+ OPENSSL_memset(table[i].Y, static_cast<uint8_t>(3 * i + 1),
+ sizeof(table[i].Y));
+ OPENSSL_memset(table[i].Z, static_cast<uint8_t>(3 * i + 2),
+ sizeof(table[i].Z));
+ }
+
+ for (int i = 0; i <= 16; i++) {
+ P256_POINT val;
+ ecp_nistz256_select_w5(&val, table, i);
+
+ P256_POINT expected;
+ if (i == 0) {
+ OPENSSL_memset(&expected, 0, sizeof(expected));
+ } else {
+ expected = table[i-1];
+ }
+
+ EXPECT_EQ(Bytes(reinterpret_cast<const char *>(&expected), sizeof(expected)),
+ Bytes(reinterpret_cast<const char *>(&val), sizeof(val)));
+ }
+
+ // This is a constant-time function, so it is only necessary to instrument one
+ // index for ABI checking.
+ P256_POINT val;
+ CHECK_ABI(ecp_nistz256_select_w5, &val, table, 7);
+}
+
+TEST(P256_NistzTest, SelectW7) {
+ // Fill a table with some garbage input.
+ alignas(64) P256_POINT_AFFINE table[64];
+ for (size_t i = 0; i < 64; i++) {
+ OPENSSL_memset(table[i].X, static_cast<uint8_t>(2 * i), sizeof(table[i].X));
+ OPENSSL_memset(table[i].Y, static_cast<uint8_t>(2 * i + 1),
+ sizeof(table[i].Y));
+ }
+
+ for (int i = 0; i <= 64; i++) {
+ P256_POINT_AFFINE val;
+ ecp_nistz256_select_w7(&val, table, i);
+
+ P256_POINT_AFFINE expected;
+ if (i == 0) {
+ OPENSSL_memset(&expected, 0, sizeof(expected));
+ } else {
+ expected = table[i-1];
+ }
+
+ EXPECT_EQ(Bytes(reinterpret_cast<const char *>(&expected), sizeof(expected)),
+ Bytes(reinterpret_cast<const char *>(&val), sizeof(val)));
+ }
+
+ // This is a constant-time function, so it is only necessary to instrument one
+ // index for ABI checking.
+ P256_POINT_AFFINE val;
+ CHECK_ABI(ecp_nistz256_select_w7, &val, table, 42);
+}
+
+TEST(P256_NistzTest, BEEU) {
+#if defined(OPENSSL_X86_64)
+ if (!CRYPTO_is_AVX_capable()) {
+ // No AVX support; cannot run the BEEU code.
+ return;
+ }
+#endif
+
+ bssl::UniquePtr<EC_GROUP> group(
+ EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
+ ASSERT_TRUE(group);
+
+ BN_ULONG order_words[P256_LIMBS];
+ ASSERT_TRUE(
+ bn_copy_words(order_words, P256_LIMBS, EC_GROUP_get0_order(group.get())));
+
+ BN_ULONG in[P256_LIMBS], out[P256_LIMBS];
+ EC_SCALAR in_scalar, out_scalar, result;
+ OPENSSL_memset(in, 0, sizeof(in));
+
+ // Trying to find the inverse of zero should fail.
+ ASSERT_FALSE(beeu_mod_inverse_vartime(out, in, order_words));
+ // This is not a constant-time function, so instrument both zero and a few
+ // inputs below.
+ ASSERT_FALSE(CHECK_ABI(beeu_mod_inverse_vartime, out, in, order_words));
+
+ // kOneMont is 1, in Montgomery form.
+ static const BN_ULONG kOneMont[P256_LIMBS] = {
+ TOBN(0xc46353d, 0x039cdaaf),
+ TOBN(0x43190552, 0x58e8617b),
+ 0,
+ 0xffffffff,
+ };
+
+ for (BN_ULONG i = 1; i < 2000; i++) {
+ SCOPED_TRACE(i);
+
+ in[0] = i;
+ if (i >= 1000) {
+ in[1] = i << 8;
+ in[2] = i << 32;
+ in[3] = i << 48;
+ } else {
+ in[1] = in[2] = in[3] = 0;
+ }
+
+ EXPECT_TRUE(bn_less_than_words(in, order_words, P256_LIMBS));
+ ASSERT_TRUE(beeu_mod_inverse_vartime(out, in, order_words));
+ EXPECT_TRUE(bn_less_than_words(out, order_words, P256_LIMBS));
+
+ // Calculate out*in and confirm that it equals one, modulo the order.
+ OPENSSL_memcpy(in_scalar.words, in, sizeof(in));
+ OPENSSL_memcpy(out_scalar.words, out, sizeof(out));
+ ec_scalar_to_montgomery(group.get(), &in_scalar, &in_scalar);
+ ec_scalar_to_montgomery(group.get(), &out_scalar, &out_scalar);
+ ec_scalar_mul_montgomery(group.get(), &result, &in_scalar, &out_scalar);
+
+ EXPECT_EQ(0, OPENSSL_memcmp(kOneMont, &result, sizeof(kOneMont)));
+
+ // Invert the result and expect to get back to the original value.
+ ASSERT_TRUE(beeu_mod_inverse_vartime(out, out, order_words));
+ EXPECT_EQ(0, OPENSSL_memcmp(in, out, sizeof(in)));
+
+ if (i < 5) {
+ EXPECT_TRUE(CHECK_ABI(beeu_mod_inverse_vartime, out, in, order_words));
+ }
+ }
+}
+
+static bool GetFieldElement(FileTest *t, BN_ULONG out[P256_LIMBS],
+ const char *name) {
+ std::vector<uint8_t> bytes;
+ if (!t->GetBytes(&bytes, name)) {
+ return false;
+ }
+
+ if (bytes.size() != BN_BYTES * P256_LIMBS) {
+ ADD_FAILURE() << "Invalid length: " << name;
+ return false;
+ }
+
+ // |byte| contains bytes in big-endian while |out| should contain |BN_ULONG|s
+ // in little-endian.
+ OPENSSL_memset(out, 0, P256_LIMBS * sizeof(BN_ULONG));
+ for (size_t i = 0; i < bytes.size(); i++) {
+ out[P256_LIMBS - 1 - (i / BN_BYTES)] <<= 8;
+ out[P256_LIMBS - 1 - (i / BN_BYTES)] |= bytes[i];
+ }
+
+ return true;
+}
+
+static std::string FieldElementToString(const BN_ULONG a[P256_LIMBS]) {
+ std::string ret;
+ for (size_t i = P256_LIMBS-1; i < P256_LIMBS; i--) {
+ char buf[2 * BN_BYTES + 1];
+ BIO_snprintf(buf, sizeof(buf), BN_HEX_FMT2, a[i]);
+ ret += buf;
+ }
+ return ret;
+}
+
+static testing::AssertionResult ExpectFieldElementsEqual(
+ const char *expected_expr, const char *actual_expr,
+ const BN_ULONG expected[P256_LIMBS], const BN_ULONG actual[P256_LIMBS]) {
+ if (OPENSSL_memcmp(expected, actual, sizeof(BN_ULONG) * P256_LIMBS) == 0) {
+ return testing::AssertionSuccess();
+ }
+
+ return testing::AssertionFailure()
+ << "Expected: " << FieldElementToString(expected) << " ("
+ << expected_expr << ")\n"
+ << "Actual: " << FieldElementToString(actual) << " (" << actual_expr
+ << ")";
+}
+
+#define EXPECT_FIELD_ELEMENTS_EQUAL(a, b) \
+ EXPECT_PRED_FORMAT2(ExpectFieldElementsEqual, a, b)
+
+static bool PointToAffine(P256_POINT_AFFINE *out, const P256_POINT *in) {
+ static const uint8_t kP[] = {
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ };
+
+ bssl::UniquePtr<BIGNUM> x(BN_new()), y(BN_new()), z(BN_new());
+ bssl::UniquePtr<BIGNUM> p(BN_bin2bn(kP, sizeof(kP), nullptr));
+ if (!x || !y || !z || !p ||
+ !bn_set_words(x.get(), in->X, P256_LIMBS) ||
+ !bn_set_words(y.get(), in->Y, P256_LIMBS) ||
+ !bn_set_words(z.get(), in->Z, P256_LIMBS)) {
+ return false;
+ }
+
+ // Coordinates must be fully-reduced.
+ if (BN_cmp(x.get(), p.get()) >= 0 ||
+ BN_cmp(y.get(), p.get()) >= 0 ||
+ BN_cmp(z.get(), p.get()) >= 0) {
+ return false;
+ }
+
+ if (BN_is_zero(z.get())) {
+ // The point at infinity is represented as (0, 0).
+ OPENSSL_memset(out, 0, sizeof(P256_POINT_AFFINE));
+ return true;
+ }
+
+ bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());
+ bssl::UniquePtr<BN_MONT_CTX> mont(
+ BN_MONT_CTX_new_for_modulus(p.get(), ctx.get()));
+ if (!ctx || !mont ||
+ // Invert Z.
+ !BN_from_montgomery(z.get(), z.get(), mont.get(), ctx.get()) ||
+ !BN_mod_inverse(z.get(), z.get(), p.get(), ctx.get()) ||
+ !BN_to_montgomery(z.get(), z.get(), mont.get(), ctx.get()) ||
+ // Convert (X, Y, Z) to (X/Z^2, Y/Z^3).
+ !BN_mod_mul_montgomery(x.get(), x.get(), z.get(), mont.get(),
+ ctx.get()) ||
+ !BN_mod_mul_montgomery(x.get(), x.get(), z.get(), mont.get(),
+ ctx.get()) ||
+ !BN_mod_mul_montgomery(y.get(), y.get(), z.get(), mont.get(),
+ ctx.get()) ||
+ !BN_mod_mul_montgomery(y.get(), y.get(), z.get(), mont.get(),
+ ctx.get()) ||
+ !BN_mod_mul_montgomery(y.get(), y.get(), z.get(), mont.get(),
+ ctx.get()) ||
+ !bn_copy_words(out->X, P256_LIMBS, x.get()) ||
+ !bn_copy_words(out->Y, P256_LIMBS, y.get())) {
+ return false;
+ }
+ return true;
+}
+
+static testing::AssertionResult ExpectPointsEqual(
+ const char *expected_expr, const char *actual_expr,
+ const P256_POINT_AFFINE *expected, const P256_POINT *actual) {
+ // There are multiple representations of the same |P256_POINT|, so convert to
+ // |P256_POINT_AFFINE| and compare.
+ P256_POINT_AFFINE affine;
+ if (!PointToAffine(&affine, actual)) {
+ return testing::AssertionFailure()
+ << "Could not convert " << actual_expr << " to affine: ("
+ << FieldElementToString(actual->X) << ", "
+ << FieldElementToString(actual->Y) << ", "
+ << FieldElementToString(actual->Z) << ")";
+ }
+
+ if (OPENSSL_memcmp(expected, &affine, sizeof(P256_POINT_AFFINE)) != 0) {
+ return testing::AssertionFailure()
+ << "Expected: (" << FieldElementToString(expected->X) << ", "
+ << FieldElementToString(expected->Y) << ") (" << expected_expr
+ << "; affine)\n"
+ << "Actual: (" << FieldElementToString(affine.X) << ", "
+ << FieldElementToString(affine.Y) << ") (" << actual_expr << ")";
+ }
+
+ return testing::AssertionSuccess();
+}
+
+#define EXPECT_POINTS_EQUAL(a, b) EXPECT_PRED_FORMAT2(ExpectPointsEqual, a, b)
+
+static void TestNegate(FileTest *t) {
+ BN_ULONG a[P256_LIMBS], b[P256_LIMBS];
+ ASSERT_TRUE(GetFieldElement(t, a, "A"));
+ ASSERT_TRUE(GetFieldElement(t, b, "B"));
+
+ // Test that -A = B.
+ BN_ULONG ret[P256_LIMBS];
+ ecp_nistz256_neg(ret, a);
+ EXPECT_FIELD_ELEMENTS_EQUAL(b, ret);
+
+ OPENSSL_memcpy(ret, a, sizeof(ret));
+ ecp_nistz256_neg(ret, ret /* a */);
+ EXPECT_FIELD_ELEMENTS_EQUAL(b, ret);
+
+ // Test that -B = A.
+ ecp_nistz256_neg(ret, b);
+ EXPECT_FIELD_ELEMENTS_EQUAL(a, ret);
+
+ OPENSSL_memcpy(ret, b, sizeof(ret));
+ ecp_nistz256_neg(ret, ret /* b */);
+ EXPECT_FIELD_ELEMENTS_EQUAL(a, ret);
+}
+
+static void TestMulMont(FileTest *t) {
+ BN_ULONG a[P256_LIMBS], b[P256_LIMBS], result[P256_LIMBS];
+ ASSERT_TRUE(GetFieldElement(t, a, "A"));
+ ASSERT_TRUE(GetFieldElement(t, b, "B"));
+ ASSERT_TRUE(GetFieldElement(t, result, "Result"));
+
+ BN_ULONG ret[P256_LIMBS];
+ ecp_nistz256_mul_mont(ret, a, b);
+ EXPECT_FIELD_ELEMENTS_EQUAL(result, ret);
+
+ ecp_nistz256_mul_mont(ret, b, a);
+ EXPECT_FIELD_ELEMENTS_EQUAL(result, ret);
+
+ OPENSSL_memcpy(ret, a, sizeof(ret));
+ ecp_nistz256_mul_mont(ret, ret /* a */, b);
+ EXPECT_FIELD_ELEMENTS_EQUAL(result, ret);
+
+ OPENSSL_memcpy(ret, a, sizeof(ret));
+ ecp_nistz256_mul_mont(ret, b, ret);
+ EXPECT_FIELD_ELEMENTS_EQUAL(result, ret);
+
+ OPENSSL_memcpy(ret, b, sizeof(ret));
+ ecp_nistz256_mul_mont(ret, a, ret /* b */);
+ EXPECT_FIELD_ELEMENTS_EQUAL(result, ret);
+
+ OPENSSL_memcpy(ret, b, sizeof(ret));
+ ecp_nistz256_mul_mont(ret, ret /* b */, a);
+ EXPECT_FIELD_ELEMENTS_EQUAL(result, ret);
+
+ if (OPENSSL_memcmp(a, b, sizeof(a)) == 0) {
+ ecp_nistz256_sqr_mont(ret, a);
+ EXPECT_FIELD_ELEMENTS_EQUAL(result, ret);
+
+ OPENSSL_memcpy(ret, a, sizeof(ret));
+ ecp_nistz256_sqr_mont(ret, ret /* a */);
+ EXPECT_FIELD_ELEMENTS_EQUAL(result, ret);
+ }
+}
+
+static void TestFromMont(FileTest *t) {
+ BN_ULONG a[P256_LIMBS], result[P256_LIMBS];
+ ASSERT_TRUE(GetFieldElement(t, a, "A"));
+ ASSERT_TRUE(GetFieldElement(t, result, "Result"));
+
+ BN_ULONG ret[P256_LIMBS];
+ ecp_nistz256_from_mont(ret, a);
+ EXPECT_FIELD_ELEMENTS_EQUAL(result, ret);
+
+ OPENSSL_memcpy(ret, a, sizeof(ret));
+ ecp_nistz256_from_mont(ret, ret /* a */);
+ EXPECT_FIELD_ELEMENTS_EQUAL(result, ret);
+}
+
+static void TestPointAdd(FileTest *t) {
+ P256_POINT a, b;
+ P256_POINT_AFFINE result;
+ ASSERT_TRUE(GetFieldElement(t, a.X, "A.X"));
+ ASSERT_TRUE(GetFieldElement(t, a.Y, "A.Y"));
+ ASSERT_TRUE(GetFieldElement(t, a.Z, "A.Z"));
+ ASSERT_TRUE(GetFieldElement(t, b.X, "B.X"));
+ ASSERT_TRUE(GetFieldElement(t, b.Y, "B.Y"));
+ ASSERT_TRUE(GetFieldElement(t, b.Z, "B.Z"));
+ ASSERT_TRUE(GetFieldElement(t, result.X, "Result.X"));
+ ASSERT_TRUE(GetFieldElement(t, result.Y, "Result.Y"));
+
+ P256_POINT ret;
+ ecp_nistz256_point_add(&ret, &a, &b);
+ EXPECT_POINTS_EQUAL(&result, &ret);
+
+ ecp_nistz256_point_add(&ret, &b, &a);
+ EXPECT_POINTS_EQUAL(&result, &ret);
+
+ OPENSSL_memcpy(&ret, &a, sizeof(ret));
+ ecp_nistz256_point_add(&ret, &ret /* a */, &b);
+ EXPECT_POINTS_EQUAL(&result, &ret);
+
+ OPENSSL_memcpy(&ret, &a, sizeof(ret));
+ ecp_nistz256_point_add(&ret, &b, &ret /* a */);
+ EXPECT_POINTS_EQUAL(&result, &ret);
+
+ OPENSSL_memcpy(&ret, &b, sizeof(ret));
+ ecp_nistz256_point_add(&ret, &a, &ret /* b */);
+ EXPECT_POINTS_EQUAL(&result, &ret);
+
+ OPENSSL_memcpy(&ret, &b, sizeof(ret));
+ ecp_nistz256_point_add(&ret, &ret /* b */, &a);
+ EXPECT_POINTS_EQUAL(&result, &ret);
+
+ P256_POINT_AFFINE a_affine, b_affine, infinity;
+ OPENSSL_memset(&infinity, 0, sizeof(infinity));
+ ASSERT_TRUE(PointToAffine(&a_affine, &a));
+ ASSERT_TRUE(PointToAffine(&b_affine, &b));
+
+ // ecp_nistz256_point_add_affine does not work when a == b unless doubling the
+ // point at infinity.
+ if (OPENSSL_memcmp(&a_affine, &b_affine, sizeof(a_affine)) != 0 ||
+ OPENSSL_memcmp(&a_affine, &infinity, sizeof(a_affine)) == 0) {
+ ecp_nistz256_point_add_affine(&ret, &a, &b_affine);
+ EXPECT_POINTS_EQUAL(&result, &ret);
+
+ OPENSSL_memcpy(&ret, &a, sizeof(ret));
+ ecp_nistz256_point_add_affine(&ret, &ret /* a */, &b_affine);
+ EXPECT_POINTS_EQUAL(&result, &ret);
+
+ ecp_nistz256_point_add_affine(&ret, &b, &a_affine);
+ EXPECT_POINTS_EQUAL(&result, &ret);
+
+ OPENSSL_memcpy(&ret, &b, sizeof(ret));
+ ecp_nistz256_point_add_affine(&ret, &ret /* b */, &a_affine);
+ EXPECT_POINTS_EQUAL(&result, &ret);
+ }
+
+ if (OPENSSL_memcmp(&a, &b, sizeof(a)) == 0) {
+ ecp_nistz256_point_double(&ret, &a);
+ EXPECT_POINTS_EQUAL(&result, &ret);
+
+ ret = a;
+ ecp_nistz256_point_double(&ret, &ret /* a */);
+ EXPECT_POINTS_EQUAL(&result, &ret);
+ }
+}
+
+static void TestOrdMulMont(FileTest *t) {
+ // This test works on scalars rather than field elements, but the
+ // representation is the same.
+ BN_ULONG a[P256_LIMBS], b[P256_LIMBS], result[P256_LIMBS];
+ ASSERT_TRUE(GetFieldElement(t, a, "A"));
+ ASSERT_TRUE(GetFieldElement(t, b, "B"));
+ ASSERT_TRUE(GetFieldElement(t, result, "Result"));
+
+ BN_ULONG ret[P256_LIMBS];
+ ecp_nistz256_ord_mul_mont(ret, a, b);
+ EXPECT_FIELD_ELEMENTS_EQUAL(result, ret);
+
+ ecp_nistz256_ord_mul_mont(ret, b, a);
+ EXPECT_FIELD_ELEMENTS_EQUAL(result, ret);
+
+ OPENSSL_memcpy(ret, a, sizeof(ret));
+ ecp_nistz256_ord_mul_mont(ret, ret /* a */, b);
+ EXPECT_FIELD_ELEMENTS_EQUAL(result, ret);
+
+ OPENSSL_memcpy(ret, a, sizeof(ret));
+ ecp_nistz256_ord_mul_mont(ret, b, ret);
+ EXPECT_FIELD_ELEMENTS_EQUAL(result, ret);
+
+ OPENSSL_memcpy(ret, b, sizeof(ret));
+ ecp_nistz256_ord_mul_mont(ret, a, ret /* b */);
+ EXPECT_FIELD_ELEMENTS_EQUAL(result, ret);
+
+ OPENSSL_memcpy(ret, b, sizeof(ret));
+ ecp_nistz256_ord_mul_mont(ret, ret /* b */, a);
+ EXPECT_FIELD_ELEMENTS_EQUAL(result, ret);
+
+ if (OPENSSL_memcmp(a, b, sizeof(a)) == 0) {
+ ecp_nistz256_ord_sqr_mont(ret, a, 1);
+ EXPECT_FIELD_ELEMENTS_EQUAL(result, ret);
+
+ OPENSSL_memcpy(ret, a, sizeof(ret));
+ ecp_nistz256_ord_sqr_mont(ret, ret /* a */, 1);
+ EXPECT_FIELD_ELEMENTS_EQUAL(result, ret);
+ }
+}
+
+TEST(P256_NistzTest, TestVectors) {
+ return FileTestGTest("crypto/fipsmodule/ec/p256-nistz_tests.txt",
+ [](FileTest *t) {
+ if (t->GetParameter() == "Negate") {
+ TestNegate(t);
+ } else if (t->GetParameter() == "MulMont") {
+ TestMulMont(t);
+ } else if (t->GetParameter() == "FromMont") {
+ TestFromMont(t);
+ } else if (t->GetParameter() == "PointAdd") {
+ TestPointAdd(t);
+ } else if (t->GetParameter() == "OrdMulMont") {
+ TestOrdMulMont(t);
+ } else {
+ FAIL() << "Unknown test type:" << t->GetParameter();
+ }
+ });
+}
+
+// Instrument the functions covered in TestVectors for ABI checking.
+TEST(P256_NistzTest, ABI) {
+ BN_ULONG a[P256_LIMBS], b[P256_LIMBS], c[P256_LIMBS];
+ OPENSSL_memset(a, 0x01, sizeof(a));
+ // These functions are all constant-time, so it is only necessary to
+ // instrument one call each for ABI checking.
+ CHECK_ABI(ecp_nistz256_neg, b, a);
+ CHECK_ABI(ecp_nistz256_mul_mont, c, a, b);
+ CHECK_ABI(ecp_nistz256_sqr_mont, c, a);
+ CHECK_ABI(ecp_nistz256_from_mont, c, a);
+ CHECK_ABI(ecp_nistz256_ord_mul_mont, c, a, b);
+
+ // Check a few different loop counts.
+ CHECK_ABI(ecp_nistz256_ord_sqr_mont, b, a, 1);
+ CHECK_ABI(ecp_nistz256_ord_sqr_mont, b, a, 3);
+
+ // Point addition has some special cases around infinity and doubling. Test a
+ // few different scenarios.
+ static const P256_POINT kA = {
+ {TOBN(0x60559ac7, 0xc8d0d89d), TOBN(0x6cda3400, 0x545f7e2c),
+ TOBN(0x9b5159e0, 0x323e6048), TOBN(0xcb8dea33, 0x27057fe6)},
+ {TOBN(0x81a2d3bc, 0xc93a2d53), TOBN(0x81f40762, 0xa4f33ccf),
+ TOBN(0xc3c3300a, 0xa8ad50ea), TOBN(0x553de89b, 0x31719830)},
+ {TOBN(0x3fd9470f, 0xb277d181), TOBN(0xc191b8d5, 0x6376f206),
+ TOBN(0xb2572c1f, 0x45eda26f), TOBN(0x4589e40d, 0xf2efc546)},
+ };
+ static const P256_POINT kB = {
+ {TOBN(0x3cf0b0aa, 0x92054341), TOBN(0xb949bb80, 0xdab57807),
+ TOBN(0x99de6814, 0xefd21b3e), TOBN(0x32ad5649, 0x7c6c6e83)},
+ {TOBN(0x06afaa02, 0x688399e0), TOBN(0x75f2d096, 0x2a3ce65c),
+ TOBN(0xf6a31eb7, 0xca0244b3), TOBN(0x57b33b7a, 0xcfeee75e)},
+ {TOBN(0x7617d2e0, 0xb4f1d35f), TOBN(0xa922cb10, 0x7f592b65),
+ TOBN(0x12fd6c7a, 0x51a2f474), TOBN(0x337d5e1e, 0xc2fc711b)},
+ };
+ // This file represents Jacobian infinity as (*, *, 0).
+ static const P256_POINT kInfinity = {
+ {TOBN(0, 0), TOBN(0, 0), TOBN(0, 0), TOBN(0, 0)},
+ {TOBN(0, 0), TOBN(0, 0), TOBN(0, 0), TOBN(0, 0)},
+ {TOBN(0, 0), TOBN(0, 0), TOBN(0, 0), TOBN(0, 0)},
+ };
+
+ P256_POINT p;
+ CHECK_ABI(ecp_nistz256_point_add, &p, &kA, &kB);
+ CHECK_ABI(ecp_nistz256_point_add, &p, &kA, &kA);
+ OPENSSL_memcpy(&p, &kA, sizeof(P256_POINT));
+ ecp_nistz256_neg(p.Y, p.Y);
+ CHECK_ABI(ecp_nistz256_point_add, &p, &kA, &p); // A + -A
+ CHECK_ABI(ecp_nistz256_point_add, &p, &kA, &kInfinity);
+ CHECK_ABI(ecp_nistz256_point_add, &p, &kInfinity, &kA);
+ CHECK_ABI(ecp_nistz256_point_add, &p, &kInfinity, &kInfinity);
+ CHECK_ABI(ecp_nistz256_point_double, &p, &kA);
+ CHECK_ABI(ecp_nistz256_point_double, &p, &kInfinity);
+
+ static const P256_POINT_AFFINE kC = {
+ {TOBN(0x7e3ad339, 0xfb3fa5f0), TOBN(0x559d669d, 0xe3a047b2),
+ TOBN(0x8883b298, 0x7042e595), TOBN(0xfabada65, 0x7e477f08)},
+ {TOBN(0xd9cfceb8, 0xda1c3e85), TOBN(0x80863761, 0x0ce6d6bc),
+ TOBN(0xa8409d84, 0x66034f02), TOBN(0x05519925, 0x31a68d55)},
+ };
+ // This file represents affine infinity as (0, 0).
+ static const P256_POINT_AFFINE kInfinityAffine = {
+ {TOBN(0, 0), TOBN(0, 0), TOBN(0, 0), TOBN(0, 0)},
+ {TOBN(0, 0), TOBN(0, 0), TOBN(0, 0), TOBN(0, 0)},
+ };
+
+ CHECK_ABI(ecp_nistz256_point_add_affine, &p, &kA, &kC);
+ CHECK_ABI(ecp_nistz256_point_add_affine, &p, &kA, &kInfinityAffine);
+ CHECK_ABI(ecp_nistz256_point_add_affine, &p, &kInfinity, &kInfinityAffine);
+ CHECK_ABI(ecp_nistz256_point_add_affine, &p, &kInfinity, &kC);
+}
+
+#endif
diff --git a/src/crypto/fipsmodule/ec/p256-nistz_tests.txt b/src/crypto/fipsmodule/ec/p256-nistz_tests.txt
new file mode 100644
index 0000000..8bc301e
--- /dev/null
+++ b/src/crypto/fipsmodule/ec/p256-nistz_tests.txt
@@ -0,0 +1,1548 @@
+# Negation tests.
+#
+# The following tests satisfy A = -B (mod P).
+
+Test = Negate
+A = 0000000000000000000000000000000000000000000000000000000000000000
+B = 0000000000000000000000000000000000000000000000000000000000000000
+
+Test = Negate
+A = 0000000000000000000000000000000000000000000000000000000000000001
+B = ffffffff00000001000000000000000000000000fffffffffffffffffffffffe
+
+Test = Negate
+A = 0000000000000000000000000000000000000000000000000000000000000003
+B = ffffffff00000001000000000000000000000000fffffffffffffffffffffffc
+
+Test = Negate
+A = 0000000000000000000000000000000000000000000000000000000000000007
+B = ffffffff00000001000000000000000000000000fffffffffffffffffffffff8
+
+Test = Negate
+A = 000000000000000000000000000000000000000000000000000000000000000f
+B = ffffffff00000001000000000000000000000000fffffffffffffffffffffff0
+
+Test = Negate
+A = 000000000000000000000000000000000000000000000000000000000000001f
+B = ffffffff00000001000000000000000000000000ffffffffffffffffffffffe0
+
+Test = Negate
+A = 000000000000000000000000000000000000000000000000000000000000003f
+B = ffffffff00000001000000000000000000000000ffffffffffffffffffffffc0
+
+Test = Negate
+A = 000000000000000000000000000000000000000000000000000000000000007f
+B = ffffffff00000001000000000000000000000000ffffffffffffffffffffff80
+
+Test = Negate
+A = 00000000000000000000000000000000000000000000000000000000000000ff
+B = ffffffff00000001000000000000000000000000ffffffffffffffffffffff00
+
+Test = Negate
+A = 00000000000000000000000000000000000000000000000000000000000001ff
+B = ffffffff00000001000000000000000000000000fffffffffffffffffffffe00
+
+Test = Negate
+A = 00000000000000000000000000000000000000000000000000000000000003ff
+B = ffffffff00000001000000000000000000000000fffffffffffffffffffffc00
+
+Test = Negate
+A = 00000000000000000000000000000000000000000000000000000000000007ff
+B = ffffffff00000001000000000000000000000000fffffffffffffffffffff800
+
+Test = Negate
+A = 0000000000000000000000000000000000000000000000000000000000000fff
+B = ffffffff00000001000000000000000000000000fffffffffffffffffffff000
+
+Test = Negate
+A = 0000000000000000000000000000000000000000000000000000000000001fff
+B = ffffffff00000001000000000000000000000000ffffffffffffffffffffe000
+
+Test = Negate
+A = 0000000000000000000000000000000000000000000000000000000000003fff
+B = ffffffff00000001000000000000000000000000ffffffffffffffffffffc000
+
+Test = Negate
+A = 0000000000000000000000000000000000000000000000000000000000007fff
+B = ffffffff00000001000000000000000000000000ffffffffffffffffffff8000
+
+Test = Negate
+A = 000000000000000000000000000000000000000000000000000000000000ffff
+B = ffffffff00000001000000000000000000000000ffffffffffffffffffff0000
+
+Test = Negate
+A = 000000000000000000000000000000000000000000000000000000000001ffff
+B = ffffffff00000001000000000000000000000000fffffffffffffffffffe0000
+
+Test = Negate
+A = 000000000000000000000000000000000000000000000000000000000003ffff
+B = ffffffff00000001000000000000000000000000fffffffffffffffffffc0000
+
+Test = Negate
+A = 000000000000000000000000000000000000000000000000000000000007ffff
+B = ffffffff00000001000000000000000000000000fffffffffffffffffff80000
+
+Test = Negate
+A = 00000000000000000000000000000000000000000000000000000000000fffff
+B = ffffffff00000001000000000000000000000000fffffffffffffffffff00000
+
+Test = Negate
+A = 00000000000000000000000000000000000000000000000000000000001fffff
+B = ffffffff00000001000000000000000000000000ffffffffffffffffffe00000
+
+Test = Negate
+A = 00000000000000000000000000000000000000000000000000000000003fffff
+B = ffffffff00000001000000000000000000000000ffffffffffffffffffc00000
+
+Test = Negate
+A = 00000000000000000000000000000000000000000000000000000000007fffff
+B = ffffffff00000001000000000000000000000000ffffffffffffffffff800000
+
+Test = Negate
+A = 0000000000000000000000000000000000000000000000000000000000ffffff
+B = ffffffff00000001000000000000000000000000ffffffffffffffffff000000
+
+Test = Negate
+A = 0000000000000000000000000000000000000000000000000000000001ffffff
+B = ffffffff00000001000000000000000000000000fffffffffffffffffe000000
+
+Test = Negate
+A = 0000000000000000000000000000000000000000000000000000000003ffffff
+B = ffffffff00000001000000000000000000000000fffffffffffffffffc000000
+
+Test = Negate
+A = 0000000000000000000000000000000000000000000000000000000007ffffff
+B = ffffffff00000001000000000000000000000000fffffffffffffffff8000000
+
+Test = Negate
+A = 000000000000000000000000000000000000000000000000000000000fffffff
+B = ffffffff00000001000000000000000000000000fffffffffffffffff0000000
+
+Test = Negate
+A = 000000000000000000000000000000000000000000000000000000001fffffff
+B = ffffffff00000001000000000000000000000000ffffffffffffffffe0000000
+
+Test = Negate
+A = 000000000000000000000000000000000000000000000000000000003fffffff
+B = ffffffff00000001000000000000000000000000ffffffffffffffffc0000000
+
+Test = Negate
+A = 000000000000000000000000000000000000000000000000000000007fffffff
+B = ffffffff00000001000000000000000000000000ffffffffffffffff80000000
+
+Test = Negate
+A = 00000000000000000000000000000000000000000000000000000000ffffffff
+B = ffffffff00000001000000000000000000000000ffffffffffffffff00000000
+
+Test = Negate
+A = 00000000000000000000000000000000000000000000000000000001ffffffff
+B = ffffffff00000001000000000000000000000000fffffffffffffffe00000000
+
+Test = Negate
+A = 00000000000000000000000000000000000000000000000000000003ffffffff
+B = ffffffff00000001000000000000000000000000fffffffffffffffc00000000
+
+Test = Negate
+A = 00000000000000000000000000000000000000000000000000000007ffffffff
+B = ffffffff00000001000000000000000000000000fffffffffffffff800000000
+
+Test = Negate
+A = 0000000000000000000000000000000000000000000000000000000fffffffff
+B = ffffffff00000001000000000000000000000000fffffffffffffff000000000
+
+Test = Negate
+A = 0000000000000000000000000000000000000000000000000000001fffffffff
+B = ffffffff00000001000000000000000000000000ffffffffffffffe000000000
+
+Test = Negate
+A = 0000000000000000000000000000000000000000000000000000003fffffffff
+B = ffffffff00000001000000000000000000000000ffffffffffffffc000000000
+
+Test = Negate
+A = 0000000000000000000000000000000000000000000000000000007fffffffff
+B = ffffffff00000001000000000000000000000000ffffffffffffff8000000000
+
+Test = Negate
+A = 000000000000000000000000000000000000000000000000000000ffffffffff
+B = ffffffff00000001000000000000000000000000ffffffffffffff0000000000
+
+Test = Negate
+A = 000000000000000000000000000000000000000000000000000001ffffffffff
+B = ffffffff00000001000000000000000000000000fffffffffffffe0000000000
+
+Test = Negate
+A = 000000000000000000000000000000000000000000000000000003ffffffffff
+B = ffffffff00000001000000000000000000000000fffffffffffffc0000000000
+
+Test = Negate
+A = 000000000000000000000000000000000000000000000000000007ffffffffff
+B = ffffffff00000001000000000000000000000000fffffffffffff80000000000
+
+Test = Negate
+A = 00000000000000000000000000000000000000000000000000000fffffffffff
+B = ffffffff00000001000000000000000000000000fffffffffffff00000000000
+
+Test = Negate
+A = 00000000000000000000000000000000000000000000000000001fffffffffff
+B = ffffffff00000001000000000000000000000000ffffffffffffe00000000000
+
+Test = Negate
+A = 00000000000000000000000000000000000000000000000000003fffffffffff
+B = ffffffff00000001000000000000000000000000ffffffffffffc00000000000
+
+Test = Negate
+A = 00000000000000000000000000000000000000000000000000007fffffffffff
+B = ffffffff00000001000000000000000000000000ffffffffffff800000000000
+
+Test = Negate
+A = 0000000000000000000000000000000000000000000000000000ffffffffffff
+B = ffffffff00000001000000000000000000000000ffffffffffff000000000000
+
+Test = Negate
+A = 0000000000000000000000000000000000000000000000000001ffffffffffff
+B = ffffffff00000001000000000000000000000000fffffffffffe000000000000
+
+Test = Negate
+A = 0000000000000000000000000000000000000000000000000003ffffffffffff
+B = ffffffff00000001000000000000000000000000fffffffffffc000000000000
+
+Test = Negate
+A = 0000000000000000000000000000000000000000000000000007ffffffffffff
+B = ffffffff00000001000000000000000000000000fffffffffff8000000000000
+
+Test = Negate
+A = 000000000000000000000000000000000000000000000000000fffffffffffff
+B = ffffffff00000001000000000000000000000000fffffffffff0000000000000
+
+Test = Negate
+A = 000000000000000000000000000000000000000000000000001fffffffffffff
+B = ffffffff00000001000000000000000000000000ffffffffffe0000000000000
+
+Test = Negate
+A = 000000000000000000000000000000000000000000000000003fffffffffffff
+B = ffffffff00000001000000000000000000000000ffffffffffc0000000000000
+
+Test = Negate
+A = 000000000000000000000000000000000000000000000000007fffffffffffff
+B = ffffffff00000001000000000000000000000000ffffffffff80000000000000
+
+Test = Negate
+A = 00000000000000000000000000000000000000000000000000ffffffffffffff
+B = ffffffff00000001000000000000000000000000ffffffffff00000000000000
+
+Test = Negate
+A = 00000000000000000000000000000000000000000000000001ffffffffffffff
+B = ffffffff00000001000000000000000000000000fffffffffe00000000000000
+
+Test = Negate
+A = 00000000000000000000000000000000000000000000000003ffffffffffffff
+B = ffffffff00000001000000000000000000000000fffffffffc00000000000000
+
+Test = Negate
+A = 00000000000000000000000000000000000000000000000007ffffffffffffff
+B = ffffffff00000001000000000000000000000000fffffffff800000000000000
+
+Test = Negate
+A = 0000000000000000000000000000000000000000000000000fffffffffffffff
+B = ffffffff00000001000000000000000000000000fffffffff000000000000000
+
+Test = Negate
+A = 0000000000000000000000000000000000000000000000001fffffffffffffff
+B = ffffffff00000001000000000000000000000000ffffffffe000000000000000
+
+Test = Negate
+A = 0000000000000000000000000000000000000000000000003fffffffffffffff
+B = ffffffff00000001000000000000000000000000ffffffffc000000000000000
+
+Test = Negate
+A = 0000000000000000000000000000000000000000000000007fffffffffffffff
+B = ffffffff00000001000000000000000000000000ffffffff8000000000000000
+
+Test = Negate
+A = 000000000000000000000000000000000000000000000000ffffffffffffffff
+B = ffffffff00000001000000000000000000000000ffffffff0000000000000000
+
+Test = Negate
+A = 000000000000000000000000000000000000000000000001ffffffffffffffff
+B = ffffffff00000001000000000000000000000000fffffffe0000000000000000
+
+Test = Negate
+A = 000000000000000000000000000000000000000000000003ffffffffffffffff
+B = ffffffff00000001000000000000000000000000fffffffc0000000000000000
+
+Test = Negate
+A = 000000000000000000000000000000000000000000000007ffffffffffffffff
+B = ffffffff00000001000000000000000000000000fffffff80000000000000000
+
+Test = Negate
+A = 00000000000000000000000000000000000000000000000fffffffffffffffff
+B = ffffffff00000001000000000000000000000000fffffff00000000000000000
+
+Test = Negate
+A = 00000000000000000000000000000000000000000000001fffffffffffffffff
+B = ffffffff00000001000000000000000000000000ffffffe00000000000000000
+
+Test = Negate
+A = 00000000000000000000000000000000000000000000003fffffffffffffffff
+B = ffffffff00000001000000000000000000000000ffffffc00000000000000000
+
+Test = Negate
+A = 00000000000000000000000000000000000000000000007fffffffffffffffff
+B = ffffffff00000001000000000000000000000000ffffff800000000000000000
+
+Test = Negate
+A = 0000000000000000000000000000000000000000000000ffffffffffffffffff
+B = ffffffff00000001000000000000000000000000ffffff000000000000000000
+
+Test = Negate
+A = 0000000000000000000000000000000000000000000001ffffffffffffffffff
+B = ffffffff00000001000000000000000000000000fffffe000000000000000000
+
+Test = Negate
+A = 0000000000000000000000000000000000000000000003ffffffffffffffffff
+B = ffffffff00000001000000000000000000000000fffffc000000000000000000
+
+Test = Negate
+A = 0000000000000000000000000000000000000000000007ffffffffffffffffff
+B = ffffffff00000001000000000000000000000000fffff8000000000000000000
+
+Test = Negate
+A = 000000000000000000000000000000000000000000000fffffffffffffffffff
+B = ffffffff00000001000000000000000000000000fffff0000000000000000000
+
+Test = Negate
+A = 000000000000000000000000000000000000000000001fffffffffffffffffff
+B = ffffffff00000001000000000000000000000000ffffe0000000000000000000
+
+Test = Negate
+A = 000000000000000000000000000000000000000000003fffffffffffffffffff
+B = ffffffff00000001000000000000000000000000ffffc0000000000000000000
+
+Test = Negate
+A = 000000000000000000000000000000000000000000007fffffffffffffffffff
+B = ffffffff00000001000000000000000000000000ffff80000000000000000000
+
+Test = Negate
+A = 00000000000000000000000000000000000000000000ffffffffffffffffffff
+B = ffffffff00000001000000000000000000000000ffff00000000000000000000
+
+Test = Negate
+A = 00000000000000000000000000000000000000000001ffffffffffffffffffff
+B = ffffffff00000001000000000000000000000000fffe00000000000000000000
+
+Test = Negate
+A = 00000000000000000000000000000000000000000003ffffffffffffffffffff
+B = ffffffff00000001000000000000000000000000fffc00000000000000000000
+
+Test = Negate
+A = 00000000000000000000000000000000000000000007ffffffffffffffffffff
+B = ffffffff00000001000000000000000000000000fff800000000000000000000
+
+Test = Negate
+A = 0000000000000000000000000000000000000000000fffffffffffffffffffff
+B = ffffffff00000001000000000000000000000000fff000000000000000000000
+
+Test = Negate
+A = 0000000000000000000000000000000000000000001fffffffffffffffffffff
+B = ffffffff00000001000000000000000000000000ffe000000000000000000000
+
+Test = Negate
+A = 0000000000000000000000000000000000000000003fffffffffffffffffffff
+B = ffffffff00000001000000000000000000000000ffc000000000000000000000
+
+Test = Negate
+A = 0000000000000000000000000000000000000000007fffffffffffffffffffff
+B = ffffffff00000001000000000000000000000000ff8000000000000000000000
+
+Test = Negate
+A = 000000000000000000000000000000000000000000ffffffffffffffffffffff
+B = ffffffff00000001000000000000000000000000ff0000000000000000000000
+
+Test = Negate
+A = 000000000000000000000000000000000000000001ffffffffffffffffffffff
+B = ffffffff00000001000000000000000000000000fe0000000000000000000000
+
+Test = Negate
+A = 000000000000000000000000000000000000000003ffffffffffffffffffffff
+B = ffffffff00000001000000000000000000000000fc0000000000000000000000
+
+Test = Negate
+A = 000000000000000000000000000000000000000007ffffffffffffffffffffff
+B = ffffffff00000001000000000000000000000000f80000000000000000000000
+
+Test = Negate
+A = 00000000000000000000000000000000000000000fffffffffffffffffffffff
+B = ffffffff00000001000000000000000000000000f00000000000000000000000
+
+Test = Negate
+A = 00000000000000000000000000000000000000001fffffffffffffffffffffff
+B = ffffffff00000001000000000000000000000000e00000000000000000000000
+
+Test = Negate
+A = 00000000000000000000000000000000000000003fffffffffffffffffffffff
+B = ffffffff00000001000000000000000000000000c00000000000000000000000
+
+Test = Negate
+A = 00000000000000000000000000000000000000007fffffffffffffffffffffff
+B = ffffffff00000001000000000000000000000000800000000000000000000000
+
+Test = Negate
+A = 0000000000000000000000000000000000000000ffffffffffffffffffffffff
+B = ffffffff00000001000000000000000000000000000000000000000000000000
+
+Test = Negate
+A = 0000000000000000000000000000000000000001ffffffffffffffffffffffff
+B = ffffffff00000000ffffffffffffffffffffffff000000000000000000000000
+
+Test = Negate
+A = 0000000000000000000000000000000000000003ffffffffffffffffffffffff
+B = ffffffff00000000fffffffffffffffffffffffd000000000000000000000000
+
+Test = Negate
+A = 0000000000000000000000000000000000000007ffffffffffffffffffffffff
+B = ffffffff00000000fffffffffffffffffffffff9000000000000000000000000
+
+Test = Negate
+A = 000000000000000000000000000000000000000fffffffffffffffffffffffff
+B = ffffffff00000000fffffffffffffffffffffff1000000000000000000000000
+
+Test = Negate
+A = 000000000000000000000000000000000000001fffffffffffffffffffffffff
+B = ffffffff00000000ffffffffffffffffffffffe1000000000000000000000000
+
+Test = Negate
+A = 000000000000000000000000000000000000003fffffffffffffffffffffffff
+B = ffffffff00000000ffffffffffffffffffffffc1000000000000000000000000
+
+Test = Negate
+A = 000000000000000000000000000000000000007fffffffffffffffffffffffff
+B = ffffffff00000000ffffffffffffffffffffff81000000000000000000000000
+
+Test = Negate
+A = 00000000000000000000000000000000000000ffffffffffffffffffffffffff
+B = ffffffff00000000ffffffffffffffffffffff01000000000000000000000000
+
+Test = Negate
+A = 00000000000000000000000000000000000001ffffffffffffffffffffffffff
+B = ffffffff00000000fffffffffffffffffffffe01000000000000000000000000
+
+Test = Negate
+A = 00000000000000000000000000000000000003ffffffffffffffffffffffffff
+B = ffffffff00000000fffffffffffffffffffffc01000000000000000000000000
+
+Test = Negate
+A = 00000000000000000000000000000000000007ffffffffffffffffffffffffff
+B = ffffffff00000000fffffffffffffffffffff801000000000000000000000000
+
+Test = Negate
+A = 0000000000000000000000000000000000000fffffffffffffffffffffffffff
+B = ffffffff00000000fffffffffffffffffffff001000000000000000000000000
+
+Test = Negate
+A = 0000000000000000000000000000000000001fffffffffffffffffffffffffff
+B = ffffffff00000000ffffffffffffffffffffe001000000000000000000000000
+
+Test = Negate
+A = 0000000000000000000000000000000000003fffffffffffffffffffffffffff
+B = ffffffff00000000ffffffffffffffffffffc001000000000000000000000000
+
+Test = Negate
+A = 0000000000000000000000000000000000007fffffffffffffffffffffffffff
+B = ffffffff00000000ffffffffffffffffffff8001000000000000000000000000
+
+Test = Negate
+A = 000000000000000000000000000000000000ffffffffffffffffffffffffffff
+B = ffffffff00000000ffffffffffffffffffff0001000000000000000000000000
+
+Test = Negate
+A = 000000000000000000000000000000000001ffffffffffffffffffffffffffff
+B = ffffffff00000000fffffffffffffffffffe0001000000000000000000000000
+
+Test = Negate
+A = 000000000000000000000000000000000003ffffffffffffffffffffffffffff
+B = ffffffff00000000fffffffffffffffffffc0001000000000000000000000000
+
+Test = Negate
+A = 000000000000000000000000000000000007ffffffffffffffffffffffffffff
+B = ffffffff00000000fffffffffffffffffff80001000000000000000000000000
+
+Test = Negate
+A = 00000000000000000000000000000000000fffffffffffffffffffffffffffff
+B = ffffffff00000000fffffffffffffffffff00001000000000000000000000000
+
+Test = Negate
+A = 00000000000000000000000000000000001fffffffffffffffffffffffffffff
+B = ffffffff00000000ffffffffffffffffffe00001000000000000000000000000
+
+Test = Negate
+A = 00000000000000000000000000000000003fffffffffffffffffffffffffffff
+B = ffffffff00000000ffffffffffffffffffc00001000000000000000000000000
+
+Test = Negate
+A = 00000000000000000000000000000000007fffffffffffffffffffffffffffff
+B = ffffffff00000000ffffffffffffffffff800001000000000000000000000000
+
+Test = Negate
+A = 0000000000000000000000000000000000ffffffffffffffffffffffffffffff
+B = ffffffff00000000ffffffffffffffffff000001000000000000000000000000
+
+Test = Negate
+A = 0000000000000000000000000000000001ffffffffffffffffffffffffffffff
+B = ffffffff00000000fffffffffffffffffe000001000000000000000000000000
+
+Test = Negate
+A = 0000000000000000000000000000000003ffffffffffffffffffffffffffffff
+B = ffffffff00000000fffffffffffffffffc000001000000000000000000000000
+
+Test = Negate
+A = 0000000000000000000000000000000007ffffffffffffffffffffffffffffff
+B = ffffffff00000000fffffffffffffffff8000001000000000000000000000000
+
+Test = Negate
+A = 000000000000000000000000000000000fffffffffffffffffffffffffffffff
+B = ffffffff00000000fffffffffffffffff0000001000000000000000000000000
+
+Test = Negate
+A = 000000000000000000000000000000001fffffffffffffffffffffffffffffff
+B = ffffffff00000000ffffffffffffffffe0000001000000000000000000000000
+
+Test = Negate
+A = 000000000000000000000000000000003fffffffffffffffffffffffffffffff
+B = ffffffff00000000ffffffffffffffffc0000001000000000000000000000000
+
+Test = Negate
+A = 000000000000000000000000000000007fffffffffffffffffffffffffffffff
+B = ffffffff00000000ffffffffffffffff80000001000000000000000000000000
+
+Test = Negate
+A = 00000000000000000000000000000000ffffffffffffffffffffffffffffffff
+B = ffffffff00000000ffffffffffffffff00000001000000000000000000000000
+
+Test = Negate
+A = 00000000000000000000000000000001ffffffffffffffffffffffffffffffff
+B = ffffffff00000000fffffffffffffffe00000001000000000000000000000000
+
+Test = Negate
+A = 00000000000000000000000000000003ffffffffffffffffffffffffffffffff
+B = ffffffff00000000fffffffffffffffc00000001000000000000000000000000
+
+Test = Negate
+A = 00000000000000000000000000000007ffffffffffffffffffffffffffffffff
+B = ffffffff00000000fffffffffffffff800000001000000000000000000000000
+
+Test = Negate
+A = 0000000000000000000000000000000fffffffffffffffffffffffffffffffff
+B = ffffffff00000000fffffffffffffff000000001000000000000000000000000
+
+Test = Negate
+A = 0000000000000000000000000000001fffffffffffffffffffffffffffffffff
+B = ffffffff00000000ffffffffffffffe000000001000000000000000000000000
+
+Test = Negate
+A = 0000000000000000000000000000003fffffffffffffffffffffffffffffffff
+B = ffffffff00000000ffffffffffffffc000000001000000000000000000000000
+
+Test = Negate
+A = 0000000000000000000000000000007fffffffffffffffffffffffffffffffff
+B = ffffffff00000000ffffffffffffff8000000001000000000000000000000000
+
+Test = Negate
+A = 000000000000000000000000000000ffffffffffffffffffffffffffffffffff
+B = ffffffff00000000ffffffffffffff0000000001000000000000000000000000
+
+Test = Negate
+A = 000000000000000000000000000001ffffffffffffffffffffffffffffffffff
+B = ffffffff00000000fffffffffffffe0000000001000000000000000000000000
+
+Test = Negate
+A = 000000000000000000000000000003ffffffffffffffffffffffffffffffffff
+B = ffffffff00000000fffffffffffffc0000000001000000000000000000000000
+
+Test = Negate
+A = 000000000000000000000000000007ffffffffffffffffffffffffffffffffff
+B = ffffffff00000000fffffffffffff80000000001000000000000000000000000
+
+Test = Negate
+A = 00000000000000000000000000000fffffffffffffffffffffffffffffffffff
+B = ffffffff00000000fffffffffffff00000000001000000000000000000000000
+
+Test = Negate
+A = 00000000000000000000000000001fffffffffffffffffffffffffffffffffff
+B = ffffffff00000000ffffffffffffe00000000001000000000000000000000000
+
+Test = Negate
+A = 00000000000000000000000000003fffffffffffffffffffffffffffffffffff
+B = ffffffff00000000ffffffffffffc00000000001000000000000000000000000
+
+Test = Negate
+A = 00000000000000000000000000007fffffffffffffffffffffffffffffffffff
+B = ffffffff00000000ffffffffffff800000000001000000000000000000000000
+
+Test = Negate
+A = 0000000000000000000000000000ffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000ffffffffffff000000000001000000000000000000000000
+
+Test = Negate
+A = 0000000000000000000000000001ffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000fffffffffffe000000000001000000000000000000000000
+
+Test = Negate
+A = 0000000000000000000000000003ffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000fffffffffffc000000000001000000000000000000000000
+
+Test = Negate
+A = 0000000000000000000000000007ffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000fffffffffff8000000000001000000000000000000000000
+
+Test = Negate
+A = 000000000000000000000000000fffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000fffffffffff0000000000001000000000000000000000000
+
+Test = Negate
+A = 000000000000000000000000001fffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000ffffffffffe0000000000001000000000000000000000000
+
+Test = Negate
+A = 000000000000000000000000003fffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000ffffffffffc0000000000001000000000000000000000000
+
+Test = Negate
+A = 000000000000000000000000007fffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000ffffffffff80000000000001000000000000000000000000
+
+Test = Negate
+A = 00000000000000000000000000ffffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000ffffffffff00000000000001000000000000000000000000
+
+Test = Negate
+A = 00000000000000000000000001ffffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000fffffffffe00000000000001000000000000000000000000
+
+Test = Negate
+A = 00000000000000000000000003ffffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000fffffffffc00000000000001000000000000000000000000
+
+Test = Negate
+A = 00000000000000000000000007ffffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000fffffffff800000000000001000000000000000000000000
+
+Test = Negate
+A = 0000000000000000000000000fffffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000fffffffff000000000000001000000000000000000000000
+
+Test = Negate
+A = 0000000000000000000000001fffffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000ffffffffe000000000000001000000000000000000000000
+
+Test = Negate
+A = 0000000000000000000000003fffffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000ffffffffc000000000000001000000000000000000000000
+
+Test = Negate
+A = 0000000000000000000000007fffffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000ffffffff8000000000000001000000000000000000000000
+
+Test = Negate
+A = 000000000000000000000000ffffffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000ffffffff0000000000000001000000000000000000000000
+
+Test = Negate
+A = 000000000000000000000001ffffffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000fffffffe0000000000000001000000000000000000000000
+
+Test = Negate
+A = 000000000000000000000003ffffffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000fffffffc0000000000000001000000000000000000000000
+
+Test = Negate
+A = 000000000000000000000007ffffffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000fffffff80000000000000001000000000000000000000000
+
+Test = Negate
+A = 00000000000000000000000fffffffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000fffffff00000000000000001000000000000000000000000
+
+Test = Negate
+A = 00000000000000000000001fffffffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000ffffffe00000000000000001000000000000000000000000
+
+Test = Negate
+A = 00000000000000000000003fffffffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000ffffffc00000000000000001000000000000000000000000
+
+Test = Negate
+A = 00000000000000000000007fffffffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000ffffff800000000000000001000000000000000000000000
+
+Test = Negate
+A = 0000000000000000000000ffffffffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000ffffff000000000000000001000000000000000000000000
+
+Test = Negate
+A = 0000000000000000000001ffffffffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000fffffe000000000000000001000000000000000000000000
+
+Test = Negate
+A = 0000000000000000000003ffffffffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000fffffc000000000000000001000000000000000000000000
+
+Test = Negate
+A = 0000000000000000000007ffffffffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000fffff8000000000000000001000000000000000000000000
+
+Test = Negate
+A = 000000000000000000000fffffffffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000fffff0000000000000000001000000000000000000000000
+
+Test = Negate
+A = 000000000000000000001fffffffffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000ffffe0000000000000000001000000000000000000000000
+
+Test = Negate
+A = 000000000000000000003fffffffffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000ffffc0000000000000000001000000000000000000000000
+
+Test = Negate
+A = 000000000000000000007fffffffffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000ffff80000000000000000001000000000000000000000000
+
+Test = Negate
+A = 00000000000000000000ffffffffffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000ffff00000000000000000001000000000000000000000000
+
+Test = Negate
+A = 00000000000000000001ffffffffffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000fffe00000000000000000001000000000000000000000000
+
+Test = Negate
+A = 00000000000000000003ffffffffffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000fffc00000000000000000001000000000000000000000000
+
+Test = Negate
+A = 00000000000000000007ffffffffffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000fff800000000000000000001000000000000000000000000
+
+Test = Negate
+A = 0000000000000000000fffffffffffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000fff000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 0000000000000000001fffffffffffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000ffe000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 0000000000000000003fffffffffffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000ffc000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 0000000000000000007fffffffffffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000ff8000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 000000000000000000ffffffffffffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000ff0000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 000000000000000001ffffffffffffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000fe0000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 000000000000000003ffffffffffffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000fc0000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 000000000000000007ffffffffffffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000f80000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 00000000000000000fffffffffffffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000f00000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 00000000000000001fffffffffffffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000e00000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 00000000000000003fffffffffffffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000c00000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 00000000000000007fffffffffffffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000800000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffff
+B = ffffffff00000000000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 0000000000000001ffffffffffffffffffffffffffffffffffffffffffffffff
+B = fffffffeffffffff000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 0000000000000003ffffffffffffffffffffffffffffffffffffffffffffffff
+B = fffffffefffffffd000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 0000000000000007ffffffffffffffffffffffffffffffffffffffffffffffff
+B = fffffffefffffff9000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 000000000000000fffffffffffffffffffffffffffffffffffffffffffffffff
+B = fffffffefffffff1000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 000000000000001fffffffffffffffffffffffffffffffffffffffffffffffff
+B = fffffffeffffffe1000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 000000000000003fffffffffffffffffffffffffffffffffffffffffffffffff
+B = fffffffeffffffc1000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 000000000000007fffffffffffffffffffffffffffffffffffffffffffffffff
+B = fffffffeffffff81000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 00000000000000ffffffffffffffffffffffffffffffffffffffffffffffffff
+B = fffffffeffffff01000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 00000000000001ffffffffffffffffffffffffffffffffffffffffffffffffff
+B = fffffffefffffe01000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 00000000000003ffffffffffffffffffffffffffffffffffffffffffffffffff
+B = fffffffefffffc01000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 00000000000007ffffffffffffffffffffffffffffffffffffffffffffffffff
+B = fffffffefffff801000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 0000000000000fffffffffffffffffffffffffffffffffffffffffffffffffff
+B = fffffffefffff001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 0000000000001fffffffffffffffffffffffffffffffffffffffffffffffffff
+B = fffffffeffffe001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 0000000000003fffffffffffffffffffffffffffffffffffffffffffffffffff
+B = fffffffeffffc001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 0000000000007fffffffffffffffffffffffffffffffffffffffffffffffffff
+B = fffffffeffff8001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = fffffffeffff0001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = fffffffefffe0001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 000000000003ffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = fffffffefffc0001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = fffffffefff80001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 00000000000fffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = fffffffefff00001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 00000000001fffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = fffffffeffe00001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 00000000003fffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = fffffffeffc00001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 00000000007fffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = fffffffeff800001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 0000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = fffffffeff000001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 0000000001ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = fffffffefe000001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 0000000003ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = fffffffefc000001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 0000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = fffffffef8000001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 000000000fffffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = fffffffef0000001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 000000001fffffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = fffffffee0000001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 000000003fffffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = fffffffec0000001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = fffffffe80000001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = fffffffe00000001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 00000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = fffffffd00000001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 00000003ffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = fffffffb00000001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 00000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = fffffff700000001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 0000000fffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = ffffffef00000001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 0000001fffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = ffffffdf00000001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 0000003fffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = ffffffbf00000001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 0000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = ffffff7f00000001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = fffffeff00000001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = fffffdff00000001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 000003ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = fffffbff00000001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = fffff7ff00000001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = ffffefff00000001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 00001fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = ffffdfff00000001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 00003fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = ffffbfff00000001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 00007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = ffff7fff00000001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = fffeffff00000001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = fffdffff00000001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 0003ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = fffbffff00000001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 0007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = fff7ffff00000001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = ffefffff00000001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 001fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = ffdfffff00000001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 003fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = ffbfffff00000001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = ff7fffff00000001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = feffffff00000001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = fdffffff00000001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = fbffffff00000001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = f7ffffff00000001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = efffffff00000001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = dfffffff00000001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = bfffffff00000001000000000000000000000001000000000000000000000000
+
+Test = Negate
+A = 7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+B = 7fffffff00000001000000000000000000000001000000000000000000000000
+
+
+# Montgomery multiplication tests.
+#
+# The following tests satisfy A * B * 2^-256 = Result (mod P).
+
+Test = MulMont
+A = e762f095431b732ce33c4f4a6f41068ff7f78e37aad940166667d193bfc58039
+B = a43df383dd5df14d7c16737b781261473f9ffb76ee29562fbb5e5d390b882fb5
+Result = cf637a47dc5fb82aed80ed4c66b682a94bf0b76a2878acf483aad86c0db7cc19
+
+Test = MulMont
+A = 2e519e860cb3f8f32fc351861b022e9fc7bb073ca8767efb3d1027dd32a38bcb
+B = 466d035e4238d6a30613dd227b0daeacd6a8634fa60f5150d42dd20601794be4
+Result = 486e1abe0f79e107f8beca6e4653872f63a24dedb005def6aae75a2a51e73c76
+
+Test = MulMont
+A = 1763859541b5e2edee019c66699d0e12e349e6ee586d618ac20c679d2fa8cadd
+B = 56125872de888c5656dec17fbf9678d915ff9815da897df81f03fd9aa4f93654
+Result = 71ce584135a0aba8222ca0021bcefac5811d19100627f96726cf195ff2ac4aad
+
+Test = MulMont
+A = ea3be6295098e4995b93267dbd58f24fd9c18f7e89e9e5aeafdc34ca54e8ec4e
+B = 2735658978d620a4f76bffe94d9cd7d683b3bfd533aa6bb2b94f52122e83f7fc
+Result = 362f7ab3a12effe9bad069b84a7df5f108503c2457f83ddb05b57f19e6457989
+
+Test = MulMont
+A = f607f087ec5015b533df8802771dc60ef1487d86ce405e5bb18f8f06ca483f13
+B = 73ac532eb3f2356a96e668f167a1626a0f7b1fd2cd84ba6deeebd01af1d3897d
+Result = ce7045e69da157e62fb42508880f5734531c36948c704aedec42afa75cb9c2eb
+
+Test = MulMont
+A = 80ce8eb07601fd8e19ba08a9d21081b0324fd459f9c489ac7c871d406133c813
+B = 7ad28cef45b137ecc5426a44b6bce6d4329f5bd2b5e55d46edd5fbb295678a1b
+Result = 04068f8461d17b34c8d9c3eecf61dbaef9cd5a952bbcd9f84bb2044f2439da60
+
+Test = MulMont
+A = 17429caf63689e143c8ca77df69a11cbc02c272daadd75a66f3fa5f88828367e
+B = 5725bedc56a4b16e0f0ae55fa0beb1fdf3ff132ccb9803bab678d4ac7915d88c
+Result = a1da0fa68947e906287ea164b213bc7e80649b2ac3f97f203549d3b270de05a1
+
+Test = MulMont
+A = e7da43c0e0fa7adeb972901bef3160c848e9651bfc810968afdb0cd598830370
+B = 08f03060cac1d3c15eea69623d5fb01da465b209e3e5e90fbb51053a1c5700eb
+Result = cda4ffaf8b1c3ac0d44bae6ea5154de11e14931747a65396531302c0cb1ed537
+
+Test = MulMont
+A = c7375c2b6666713cb33cfb741268fd3ccf703bcaa0b9b27f84a8cb970655da9c
+B = b0796ee4bb88b9bad895d9c25c34f43a3941e9585bda8e86ff4fa0bbb391ac61
+Result = fd1d557a9fb0031e462121bf7ca31804acfcfce822bb6ee6631b54c575380617
+
+Test = MulMont
+A = 72a87b13eb4a2e248214aa591c586df65790f9f750a1641b47581a4ee09be7e9
+B = 38e602844b9aaf737e8b1261110b86ba22806ccbbbfdc5305075429d7ce4f002
+Result = cb2d63ee829de8801759f0229d4c07139bacd804f0c815d35004747c65bffdf2
+
+# Test cases where A == B to test squaring.
+
+Test = MulMont
+A = 0000000000000000000000000000000000000000000000000000000000000000
+B = 0000000000000000000000000000000000000000000000000000000000000000
+Result = 0000000000000000000000000000000000000000000000000000000000000000
+
+Test = MulMont
+A = 579e9ce1ad00639b8b64d49546ff4f9c30ad12eaebe9e2ed91e97d55c3c5d847
+B = 579e9ce1ad00639b8b64d49546ff4f9c30ad12eaebe9e2ed91e97d55c3c5d847
+Result = 10c5e60c2d480d5d53f50c24fb771fd2dec208db04624dfd05d2847ca173a9aa
+
+Test = MulMont
+A = 501947209b121bcdedce8c895ee2ba310f2e561e97998eb8f3b99d1f924f36c1
+B = 501947209b121bcdedce8c895ee2ba310f2e561e97998eb8f3b99d1f924f36c1
+Result = 54d6d64566619b215910f1b9e467b22ef205ca3aaad37a00fcbd906357f9c179
+
+Test = MulMont
+A = e84ab9202722498baa2c9158f40d47b1f03df4d13976b0aec916a937e99f3a89
+B = e84ab9202722498baa2c9158f40d47b1f03df4d13976b0aec916a937e99f3a89
+Result = 9af01fa6947a60679b6f87efe9b6fba97baf5d55a19d5e91dd5da1da10caeebf
+
+Test = MulMont
+A = add67c61d8479570f45a59e9b04974f970b0c4c6c046056fea1bdf3f0e7d3152
+B = add67c61d8479570f45a59e9b04974f970b0c4c6c046056fea1bdf3f0e7d3152
+Result = c0c68b4327e3fe7e0522167a54b25aaa6f76085ce4f6550479c89f3f1c39dd18
+
+Test = MulMont
+A = 434ef0db5640a3ea63125f815bc3cb3c92d06dbc3b5cb484e01b5247b3b4bfe5
+B = 434ef0db5640a3ea63125f815bc3cb3c92d06dbc3b5cb484e01b5247b3b4bfe5
+Result = b5105d16b858279247ed31362a90260978d64e0492e84bffa7a0e13ee1541544
+
+Test = MulMont
+A = b1db42aa4b259d9c6104599aff622114f10c327d02c5640b74cf1742adff332d
+B = b1db42aa4b259d9c6104599aff622114f10c327d02c5640b74cf1742adff332d
+Result = 0c175e7f96fc62059864c561d99a8d90978c72757ba305cd8862ed6a5fadad59
+
+Test = MulMont
+A = 7610271796be25416b652badd3119938974b20d4fc92244aea76d23b80d178f0
+B = 7610271796be25416b652badd3119938974b20d4fc92244aea76d23b80d178f0
+Result = 67d76e4a7c8355bb362481a76a63b365ad79767cc672b174130e833d41ca5709
+
+Test = MulMont
+A = 3480d60b0ccafca89c86f22f78380cead81310241f27a815e6fd21c2060caed8
+B = 3480d60b0ccafca89c86f22f78380cead81310241f27a815e6fd21c2060caed8
+Result = 68bfb2652d3bf03d17b20b2c52c68e847b0006047ba4ea81d4b85af2e0a21f72
+
+Test = MulMont
+A = 8ad6fa8bf3fe56ece1d0970636c1429ed5dfc2441c3194928a6348b69490b537
+B = 8ad6fa8bf3fe56ece1d0970636c1429ed5dfc2441c3194928a6348b69490b537
+Result = f5cdccf29e09928722137fb5a5ec035d7f39580838e19b892a7a972866330318
+
+Test = MulMont
+A = 71c328ce472ae74b5028b21f9d1997e0f7dbcee979a8f9fdecfa5d37d359c835
+B = 71c328ce472ae74b5028b21f9d1997e0f7dbcee979a8f9fdecfa5d37d359c835
+Result = c3472fafd01fc3ed93a91ab65411cb852bd5839603a02ca6cdfbadcb9ac474a0
+
+
+# Montgomery conversion tests.
+#
+# The following tests satisfy A * 2^-256 = Result (mod P).
+
+Test = FromMont
+A = 0585a3dada9bb283fd8db4fc46c106d28f95b8cf159a405891196dbb9ce0b5cf
+Result = d198d054d25a069c40cdeeb968a5562a67c3ef659297169e4be872f234897dc0
+
+Test = FromMont
+A = 9ff49a4a3f810fd34ca6f37fb1b3c40e61bc0492227e91e41cbe06bd58ba65b8
+Result = 326a061b2047d9ba4eddaba9b1fe253d5b2a24e268e3f8810767bef8cda07643
+
+Test = FromMont
+A = 05a69f8f646494be65affbd44d0536ca098d6f3640e80b5e48764ab78928cf58
+Result = 5a6f9c7025d4063480c400fe6f271cf3a3d2c43f9e1ceac21a88208c28329731
+
+Test = FromMont
+A = 256481a9e52d692719330a6f1208d9eca4ddd919aee06e234cbbde77d245501b
+Result = fe9fc86a2ff61a0c981d5e86c5472248e071e9639521c5be43947bfffc7d5858
+
+Test = FromMont
+A = 2062ef333cadefc36ced52a2ea7e4215b1fca29283baa1e3be76e321f1b213f0
+Result = 961ce39c3bf1d699b4b61ded8a5beae6eb6185d21f1df435b079b1f6a79dc738
+
+Test = FromMont
+A = 97241c3651a8f9d2fc02730f15c3e09e48d2e645cfe927385cb81d3f454414fb
+Result = 2114225803efe7b6c7fbb290cb946da4e78697aad5624c2d3fe9fb568460b93c
+
+Test = FromMont
+A = 1aae0ad2c8ac988e11beda32ca7257f4d4de41f4b74452fa46f0a3bafb39262a
+Result = 77c884131c34a2c3acce8a69dc5cf55987b7999c70586a9ef3c0dfb634900296
+
+Test = FromMont
+A = 034de033e2d38cf8bec8a994414b64a2fce7c83c5d81efc3d21448225071e85d
+Result = 984fecbde84f393133fb602777b4395c56449d2cbbd7d8ae428b2ee6f82a2956
+
+Test = FromMont
+A = d2b296c2004b2761b6781311c924cbf5ff56dcc0900ed5cd24f5dd2e07f32633
+Result = ddcff6e031b859a814ce8f37b71c10cd5fb642af54af72deabb95adcb99307b1
+
+Test = FromMont
+A = 8f525e6af50a62fc176dec75bdf48f70ba8ab97323ba78c643ef07f6457ba070
+Result = 8fa95d57aae2fff79045654501478f7a394b27b8b54113a25ac74662606f767c
+
+
+# Point adding tests.
+#
+# The following tests satisfy Result = A + B. Result is in affine coordinates,
+# with infinity represented as (0, 0). A and B are in Jacobian coordinates. All
+# field elements are fully reduced and in the Montgomery domain.
+
+# ∞ + ∞ = ∞.
+Test = PointAdd
+A.X = 0000000000000000000000000000000000000000000000000000000000000000
+A.Y = 0000000000000000000000000000000000000000000000000000000000000000
+A.Z = 0000000000000000000000000000000000000000000000000000000000000000
+B.X = 0000000000000000000000000000000000000000000000000000000000000000
+B.Y = 0000000000000000000000000000000000000000000000000000000000000000
+B.Z = 0000000000000000000000000000000000000000000000000000000000000000
+Result.X = 0000000000000000000000000000000000000000000000000000000000000000
+Result.Y = 0000000000000000000000000000000000000000000000000000000000000000
+
+# ∞ + ∞ = ∞, with an alternate representation of ∞.
+Test = PointAdd
+A.X = 33c0d6224957b40403366bcf638f29928c2b9bcc74a0bac58808b02040781420
+A.Y = f9698d488fd517306a66a397e92542d435a7ee54e978c2b4782da38fcf613c6e
+A.Z = 0000000000000000000000000000000000000000000000000000000000000000
+B.X = 5dd08e3206a651cf2320dc98a3a173baef07fbd04bdc6eee2d79ddb13c63ac2e
+B.Y = 2270fd1d5dde52ec8f1e53816c2a0fcc9836d990894106894d8f99e89edbc335
+B.Z = 0000000000000000000000000000000000000000000000000000000000000000
+Result.X = 0000000000000000000000000000000000000000000000000000000000000000
+Result.Y = 0000000000000000000000000000000000000000000000000000000000000000
+
+# g + ∞ = g.
+Test = PointAdd
+A.X = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c
+A.Y = 8571ff1825885d85d2e88688dd21f3258b4ab8e4ba19e45cddf25357ce95560a
+A.Z = 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
+B.X = 0000000000000000000000000000000000000000000000000000000000000000
+B.Y = 0000000000000000000000000000000000000000000000000000000000000000
+B.Z = 0000000000000000000000000000000000000000000000000000000000000000
+Result.X = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c
+Result.Y = 8571ff1825885d85d2e88688dd21f3258b4ab8e4ba19e45cddf25357ce95560a
+
+# g + ∞ = g, with an alternate representation of ∞.
+Test = PointAdd
+A.X = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c
+A.Y = 8571ff1825885d85d2e88688dd21f3258b4ab8e4ba19e45cddf25357ce95560a
+A.Z = 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
+B.X = edc21713cc3b51b9632b37925b5369a13aa3eab989f2d9a720154c1786eca076
+B.Y = 8da43525eb9de2a56c5a3fd7447258d96ccb60337e474b830d1fa37c0da1da8f
+B.Z = 0000000000000000000000000000000000000000000000000000000000000000
+Result.X = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c
+Result.Y = 8571ff1825885d85d2e88688dd21f3258b4ab8e4ba19e45cddf25357ce95560a
+
+# g + -g = ∞.
+Test = PointAdd
+A.X = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c
+A.Y = 8571ff1825885d85d2e88688dd21f3258b4ab8e4ba19e45cddf25357ce95560a
+A.Z = 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
+B.X = 18905f76a53755c679fb732b7762251075ba95fc5fedb60179e730d418a9143c
+B.Y = 7a8e00e6da77a27b2d17797722de0cda74b5471c45e61ba3220daca8316aa9f5
+B.Z = 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
+Result.X = 0000000000000000000000000000000000000000000000000000000000000000
+Result.Y = 0000000000000000000000000000000000000000000000000000000000000000
+
+# Test some random Jacobian sums.
+Test = PointAdd
+A.X = cb8dea3327057fe69b5159e0323e60486cda3400545f7e2c60559ac7c8d0d89d
+A.Y = 553de89b31719830c3c3300aa8ad50ea81f40762a4f33ccf81a2d3bcc93a2d53
+A.Z = 4589e40df2efc546b2572c1f45eda26fc191b8d56376f2063fd9470fb277d181
+B.X = 32ad56497c6c6e8399de6814efd21b3eb949bb80dab578073cf0b0aa92054341
+B.Y = 57b33b7acfeee75ef6a31eb7ca0244b375f2d0962a3ce65c06afaa02688399e0
+B.Z = 337d5e1ec2fc711b12fd6c7a51a2f474a922cb107f592b657617d2e0b4f1d35f
+Result.X = 120c6ddd6f8ebc798c5740005bad5a2586575202df9cc3dd07401fe84d8cfdd4
+Result.Y = 966bc89126349ce41738be691f32c1a068e54a654ab2cb0eac39ef15ee17f0df
+
+Test = PointAdd
+A.X = a858b5249026ccc4d25fbd85db17826afa3c5963c26815cbf8511d84dce62a25
+A.Y = bd753e125579388da968036d50067fe0e8eccb531c4d6f1a69c61bc8259c6d76
+A.Z = 82f9cdd9abf991ac27f0caa494b7b7b2851cc6591c6362ef02d1bd2c33fd116c
+B.X = 3e5790fd7ff28a376586c8ef5625b906f2d5d7e6656191f5a530154eecd4c988
+B.Y = 6e6c91011cc5996a7db4e5539eee635ce84780a85a17778da06353048fdf6bd3
+B.Z = a9ef3402e9f15e7a91aef4a53431b2b2068914e4a09ebdafc8aa654351f32331
+Result.X = de9d6bb4dfdee64193d3eaebb9208a86e764b80e1459fd10a2e01c202e33c5e2
+Result.Y = 370e67dbb7cfa6b79adaeec48b1535f0c329856401102d546c695d0dfe1d0db5
+
+Test = PointAdd
+A.X = a2d85e21bf520691b397ac9e0c1360218cef96a8a6f4c2b24d21791360ce4d9e
+A.Y = 0cc1c5493edf586cd24f7a9f40185c1ceefa727369ed159a9fc09b700ba64f78
+A.Z = ad3083a5bd23ee1fdbd3a25abdee815052209bb1a8b22d3f7d8600442b760a61
+B.X = 7d8850dafe2c48d86b6c3f3f44453670aa7169712238d024dbd08cb4e95b9cc1
+B.Y = 6a2698c143609306fe2c402acdf26e3b42874f5ae3ea2e95898c305e791984b8
+B.Z = c81bc8988c6edabf4a03fcc456ce0c445e225c33b76a79552af0b818350ad6b0
+Result.X = 67c5f8af069b5a5636647eee50da847dff8f5f6ef71780a5d1330453db5c8a04
+Result.Y = cec9200fa541b602d94c694f1289d1d073e64f47054baa40a9921c20ca090643
+
+Test = PointAdd
+A.X = 4f9a035ffeddcc36846906cacc812ffae7f3110fe46bf7da12d0b19ec54c3873
+A.Y = 73539ed620938543f94c358dba87319dca40ae4d13d0a888527f007d26d73d74
+A.Z = 922e97056fbf12d89984346368087375560990c3fb2f337d9f46429f2022d634
+B.X = de6fa333804b1da9f046896634e498d5f456288f8f03cc41fc7ba4b1e978429a
+B.Y = fd45f1d5e905c448b947fd65bc2897928d6014425c8c502a1b2838ba882f5813
+B.Z = 50bb4c98bce36b8aad5662b8db35428bb5c1f298e17347caa5d4f542f278a1d9
+Result.X = 5c3cb05b52ec59f3cbb666b0059163afae885676cf81d64cadc943a1c0bb3a86
+Result.Y = 2871d088271faa9258e60ff28115f72294b938ef3d7b927e59177f9b41d5747e
+
+# Test some random Jacobian doublings.
+Test = PointAdd
+A.X = 75da62f76d1887e18a06483bb6b53c3ec42879ed73b7851ed4748e307653714c
+A.Y = a6f0d0d3bb492bf488d99d549aff3f0c3a48f0c35a5931578fe697b8c5f486f7
+A.Z = 6d6a50229164869f24865148a19a24d57d94ebd09dc06b5e4fc3946a95f9124f
+B.X = 3b225af8c7b6155d66061c75a03d23d94e01a2167fa7f44c5bd1e9d9c48c7421
+B.Y = af58b0e38531d1e08187c61a36b33693ef534ecae23dca4542667d93f1844d75
+B.Z = 86ed2be859c4af1d5cf99041840f3bcb7c9b8e8986811393c96e8bf57fcad872
+Result.X = ab0f931fb86a621102e67336eadcf01afe3127aeaf5b4f89e8f34628c8e1afd9
+Result.Y = 52c50e2783d69dde29d6bc75fa359ffe72e7115c2fc89a9699a499cac25e3383
+
+Test = PointAdd
+A.X = f0d499f2e3775de88ed997feeb4589506f061f93766abb0c1251d25630c4c24d
+A.Y = e8de27c3369ba718adbab5597fbaad9581f5b59ae3b758e7d664bae81d895be4
+A.Z = c62dc820a597f75518734f12b2d3c076e5b872303e37b3663636912ade79c058
+B.X = c2845b3faaa995eb88e13a44b08d8a6fdb37103f7bbcc585302c9d090be3fc5b
+B.Y = 733e5ef1b0314754b70b5b98da63cbb7475918ddb85a715e21aade0c2f2e5611
+B.Z = b8505e4a057d108b49f5d0b20884674be18bba48bbc37f765c2c32c5cc4aba5d
+Result.X = 266f2961b9352b44e61902a235b33f766f82f8199c176920dae25ad2cbad5cc9
+Result.Y = 8560e62047908b13c4247b7e4d2657f2bdecab41e73c846ba18523e5f2918a9b
+
+Test = PointAdd
+A.X = f0ca07297738d8687bffcd3f1433966241f437fa1c3381cf2d13f0fc714bc83a
+A.Y = 1181b9d61c6982e743f1c32de5d14da745290ecaf27297c36ff3ef20a7526a55
+A.Z = 93159618ca5a9f9240df7016ddc983e046126d1290e14478dfcc6a4bae9090bd
+B.X = 3a2d75803ccad665f6b785c828eaa96821cb0e81979641b9e59b5fd488fcc755
+B.Y = 99e7f820abdbcdda23d90a88788e30d67303dac86987816dbbed447431e33f3f
+B.Z = a870186c8137cdbd247d16f3aa18782de1e4c5848f49da3437223eb13d7a9ae2
+Result.X = 36a104368d39214d5a3a1a348a1de1389d1aa23009aee37464b5b3256ed4b28c
+Result.Y = da5b14dbd75f6c333929bdff88e53af7253c27e166e15ead6d778631036b7d38
+
+Test = PointAdd
+A.X = a6256508926caca56a31414aba2d5f5b04dcabdb065352a572e215b043df6e01
+A.Y = e6567d330ffb11a86ec29b406b8e3d5cce8ca46f55f38515d842dd856d6852dd
+A.Z = ec172618c8cdbfc0f4fd6dffb77858bb292f229e6d10b5c70d0d9ba75fa3ab44
+B.X = 0251f6715dbba02e6072c12ab1f89a562d35ed0ff68e021b3b5276b9faf57c52
+B.Y = d2d74ff4740ad968fa7e816bc2178458efee797669bef2e634e2857de1658e62
+B.Z = abbecea633d31f569297a4a9ec28f708c7a097cb2423ebaca66ac0e42b1c8ee4
+Result.X = d2a071d4dd72ad7e63834b58b23c4a034ed7950f5c80fad51bf96959b535d55b
+Result.Y = 3cb8dcbe25f49099b9d8dd1a9cb6073368bf6556130f2aa02637dfcff430e869
+
+# Test some random affine sums.
+Test = PointAdd
+A.X = fabada657e477f088883b2987042e595559d669de3a047b27e3ad339fb3fa5f0
+A.Y = 0551992531a68d55a8409d8466034f02808637610ce6d6bcd9cfceb8da1c3e85
+A.Z = 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
+B.X = 3a831cf2b316ce371994a5622e31749407fdf59660dc88322d14c37ebb2d68d2
+B.Y = 849c511908abdfa2bcadc43f9beae88052fdb00573c783fbb1b34b99687b9a6b
+B.Z = 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
+Result.X = d5dc9241b457d33b9bda849fb7aba8baaff8b6eea92974a8adf4b95fbfa849f0
+Result.Y = 089a66780811a8ce455c139c4bea6c5c16234c095a41b9e31c617689bdc6bd0f
+
+Test = PointAdd
+A.X = 9dfe6299e62453bb943356b6f7d90c8b6c646728ba3550bb7c1548f2ba5920cb
+A.Y = 60a4e342a89837c0e7d61c0e3e88a943633028f5260eff6af5ae8a6063f7a5da
+A.Z = 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
+B.X = 924d7305f867afecd3cc550f4c05c83a2b4c981ba0e7ff20fd2035fabe2ccc92
+B.Y = 73934620746c23be03a40edb0662c09ef1776506bd50d6397c2654d340629bf5
+B.Z = 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
+Result.X = 7384f658ccbe08afcf6b423bfdd092a8a95b03d81254a519b31517b9b9670155
+Result.Y = e922a56146b94776f805a0fbdee9084dd87be1df54f76145bf83e07cd31a083a
+
+Test = PointAdd
+A.X = 9b6642b661f06c5b3ef2a0950b3c03d35f42d3d0dcbe105a895f40132c40bd9e
+A.Y = 90cbe0ed40e47923257f064886f1e309a310cb82fc21282f8e8fa4f6c975aed6
+A.Z = 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
+B.X = 587f6b4c4bb3ab3d59ba8d31457615b3df9f9f9466df3563f4419db731f494ea
+B.Y = 38135b314572346439c8d4535b892a26e5da650ae1dc9ac2d5aeb85ade24174f
+B.Z = 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
+Result.X = 97e94b6d485f8de6779e4ad19cc7bede6d70ff4853a56eb6d5fd4e5caac60858
+Result.Y = 303bf4d62cf569370ae5393fac46b64efe98ee8222b9982bc3dc61b8e32411c5
+
+Test = PointAdd
+A.X = da49658b6c64fc7a7441b177987abbbdbfcfc3c2c569ed97696d706f7af91ca0
+A.Y = 9a66906a6e313603e9d78f99fbbda837e521e75bbbad9455ffd43f51f5e30ee5
+A.Z = 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
+B.X = fe32e5885d0005fa1962166142d2aea201af9c4ca41cdddc5446dc2472f71f42
+B.Y = a2f9b4d35ea19303a101034e96870a7caed371a980965bf86291b03b5c85af60
+B.Z = 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
+Result.X = 5375c5ea3e33c1862ca5f09322ce2012c2b4fbee9a299b66e4882e016908cc2a
+Result.Y = 936e4f12ed144cf6fcd0ab085a4929e5e3e7c28641692b1fc2ad9a3b3d447b31
+
+# Test some random affine doublings.
+Test = PointAdd
+A.X = b148cad109d4b24342eb3a03ccaa10dfd6101edf9548b1d1442b61982a4e332c
+A.Y = 7daac293162a8ee2592529630f5bd1eae96659d27c045898d33833999cd076ba
+A.Z = 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
+B.X = b148cad109d4b24342eb3a03ccaa10dfd6101edf9548b1d1442b61982a4e332c
+B.Y = 7daac293162a8ee2592529630f5bd1eae96659d27c045898d33833999cd076ba
+B.Z = 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
+Result.X = ad00fae6ab0898f7d5eeeffe8c94b302060fba2b191a2d342a8a302998ebe566
+Result.Y = 9ee46ba864901cad75169cdea023d7e64da39315e2fec1703fad6b613eb24006
+
+Test = PointAdd
+A.X = f21318618205f4967c4f47c9bc3cea41e144dc01830d087414da8dcb16d37cb3
+A.Y = 76cebf81ecc696024fe949191dc49b245ef8cc0d55ada88abf481ddad9eb6129
+A.Z = 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
+B.X = f21318618205f4967c4f47c9bc3cea41e144dc01830d087414da8dcb16d37cb3
+B.Y = 76cebf81ecc696024fe949191dc49b245ef8cc0d55ada88abf481ddad9eb6129
+B.Z = 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
+Result.X = ad8e13b721bcbfc0fe629465cda5fee3494785d51dbe65f1e13429f52c83f03e
+Result.Y = 85722e168d89543dce293428e75d52765d0935bde2ef5c45a088222db0dbbeb5
+
+Test = PointAdd
+A.X = 8797ff95334b238dadf0cb3d4dc9350678f4c7fc520089ecb70ab419510f2331
+A.Y = 326c7583d54dde377fa9193c8588912c4db2219e1bb383ab13902187e5ef76ce
+A.Z = 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
+B.X = 8797ff95334b238dadf0cb3d4dc9350678f4c7fc520089ecb70ab419510f2331
+B.Y = 326c7583d54dde377fa9193c8588912c4db2219e1bb383ab13902187e5ef76ce
+B.Z = 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
+Result.X = e91c8ec9611de8e44e0d882df59f4fae8d15e3867858fb155256a4a2f154bbc4
+Result.Y = c12be21033c6dcea7e7d7262c47876d099aead75d8b025e45ce7986193fc6f8a
+
+Test = PointAdd
+A.X = 2f4cba9543c9537e393f126e31bedb521dc0a74a940e731800e5e39cdece355d
+A.Y = 1a0957898b746b7dbc9245acd0c6df9e6adca4d8537454c9f318a8ce7c3875c4
+A.Z = 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
+B.X = 2f4cba9543c9537e393f126e31bedb521dc0a74a940e731800e5e39cdece355d
+B.Y = 1a0957898b746b7dbc9245acd0c6df9e6adca4d8537454c9f318a8ce7c3875c4
+B.Z = 00000000fffffffeffffffffffffffffffffffff000000000000000000000001
+Result.X = 5cdc40808120b68e3131bd6ed70a5ce6618f960e4d540baa582afc71be97c65d
+Result.Y = 1926a2c9f5b2d3d1dff784623fe6efe2ac629395101d38db0eff5e540bfeacb0
+
+
+# Scalar montgomery multiplication tests.
+#
+# The following tests satisfy A * B * 2^-256 = Result (mod N).
+
+Test = OrdMulMont
+A = 0000000000000000000000000000000000000000000000000000000000000000
+B = b4e9b0aea84aa5ed86964a22881a4d0e58f88e9225f30990c18751e7d4b9ec95
+Result = 0000000000000000000000000000000000000000000000000000000000000000
+
+Test = OrdMulMont
+A = 00000000ffffffff00000000000000004319055258e8617b0c46353d039cdaaf
+B = 5d24e62244973fbd829573d5a579b4e89a6512933a2c3d255bbdbc1c89028323
+Result = 5d24e62244973fbd829573d5a579b4e89a6512933a2c3d255bbdbc1c89028323
+
+Test = OrdMulMont
+A = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550
+B = abafdc695e4c2c850f8fc60f1efdbf7406a3cd2c6c59bb7e608985723896c187
+Result = 917b1214c7b31a7ee7e53be0b41a139e435ff576b51ec6af1e1a944412bea38b
+
+Test = OrdMulMont
+A = cf0f01b83670a1c79154ea16f3574ca2d4c688a3c3b6017795cbe54854418904
+B = c5ec4d3b00fb2e11fb3b1aa09e60f7d187f7c515977d1343dab9745961fcbb43
+Result = 7aaddcee32e3b340af5ad06f854284cbbce5a1ab919e9b7771c3b0e937093438
+
+Test = OrdMulMont
+A = 50023f9913879ac4020bc45a89a0ea89082db6265b96b851af29969dd8a9661c
+B = 7c165b1cba80808db114441563aa0fbfba41b9e8acff77312a2dd2138b74ef89
+Result = 3d2ca1705d8d38cbc76a5409c6535044733cafcb95d12654af1d14de177978b5
+
+Test = OrdMulMont
+A = 4d5341ea735e53d2e4f2934755642adee209bd0e5a1506206513227f3c48b270
+B = 6e48f2b60eb8fb86760134abaf3d61692557862924069c599ceb31309ea18704
+Result = 37cde3e35c814d4287bd345b910d687983929907b7a08afa2acd8596832ea86c
+
+Test = OrdMulMont
+A = 33d06c3f5a595a41a6f9c4356f8ab2b8c550d4c64b806eab5560af247c5fa9ed
+B = 0e52f34adf5754343bcf3529d652620da3c05b5dd9cdcddfb08b674a1ad21a09
+Result = 9dc64d7b4c1bc33b930e0daee2a24fc41f770378659ee71b846d2239b0fea8ea
+
+Test = OrdMulMont
+A = 8f211780cce4f93b7193b9378e6f83e1147fb3602b052eef782de8cc833e54ab
+B = e1e4f7f1feb15be64292cff86b47cd9730bcb15b133340022b824d591a660cdf
+Result = dfa2b683b1ae23027c7c109e0abb40a1366eda027ad2cad1a09061a57bee391f
+
+Test = OrdMulMont
+A = 803c279c7e4c11a5568290c0a5789ceab6860f51a942bf646501a45e1ec0a6bf
+B = c0a1145a12037129c571f5f939bf16ea0b8b480f08ec774c045d059841f7d5ed
+Result = ab48fa3b4aa692a7c077cc55ee3c3fff895118a23728c2fa5f361b30730d955a
+
+Test = OrdMulMont
+A = 0e5c95158297d75dbf0b02c3090730f65bf14704495b14837dd907af569407f1
+B = 5a03e3787c8772b2fb7ab07d7fe7fe653a58bdae7fde3174c6ed305e524f5728
+Result = 71296d305dcf9ce39010ea4f4bbf9f7c1064a413597bdc7574c13dea3fa514dc
+
+Test = OrdMulMont
+A = 366299be07886f7846fc74231db624b169360e3c8f60196a1afc9f2101e03922
+B = d6d7c830a6edb6861868b964519a6b68f6f24f7c09d66003f3f88eadd1e00158
+Result = 0b89596bf5054ebe95a39dab6e975b58190160610b09b2a4f93331ecc0e79fd3
+
+Test = OrdMulMont
+A = 8f36f0ef275a72192c3b7388e84df2b8acf66fc53aaf556e3be05c76b3f782c0
+B = 704e519363d44e8df8d91f5f347eb61e8d3e85c8fc1b82980c370a379b2bc81c
+Result = b70a392e3ce5e85b5efbbded9b8c16a3068ba9b93b4cbed9a9a71dffaad6b58a
+
+Test = OrdMulMont
+A = bf4466ef4dea9f06f0f3b4f14e01140a774262c7e0706584f4d7dac19be46d58
+B = 4af12d528b2cef0f6714961bca2ab682f8abaa97600ea8181f71563d56f8a9f5
+Result = 7b6827c0881b9846e32499e13277efb07917cf4b8c8c72bfb3daa8c1786a8e15
+
+
+# Test cases where A == B to test squaring.
+
+Test = OrdMulMont
+A = 0000000000000000000000000000000000000000000000000000000000000000
+B = 0000000000000000000000000000000000000000000000000000000000000000
+Result = 0000000000000000000000000000000000000000000000000000000000000000
+
+Test = OrdMulMont
+A = 00000000ffffffff00000000000000004319055258e8617b0c46353d039cdaaf
+B = 00000000ffffffff00000000000000004319055258e8617b0c46353d039cdaaf
+Result = 00000000ffffffff00000000000000004319055258e8617b0c46353d039cdaaf
+
+Test = OrdMulMont
+A = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550
+B = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550
+Result = 60d066334905c1e907f8b6041e607725badef3e243566fafce1bc8f79c197c79
+
+Test = OrdMulMont
+A = da43b8dd7fe8830a4fe8980ec585ccbe903a2965a695cdff398200b74b2ede41
+B = da43b8dd7fe8830a4fe8980ec585ccbe903a2965a695cdff398200b74b2ede41
+Result = 5ec68604412205b380e26ee4e4081eccc10ac7d1417b09cd534f8517b0de81ec
+
+Test = OrdMulMont
+A = a82a2b8bdbf8a37dc7cb5799691494a8c9fbf649686a4d250dc30697feb0fa47
+B = a82a2b8bdbf8a37dc7cb5799691494a8c9fbf649686a4d250dc30697feb0fa47
+Result = 552c094a8841621d6cc26b3b54ce5da5664283888445196a6433d3cfdcad3aee
+
+Test = OrdMulMont
+A = d785006e250410d9dcc6d7740795a7374c25b00b9c9a37b8285694a07307eacd
+B = d785006e250410d9dcc6d7740795a7374c25b00b9c9a37b8285694a07307eacd
+Result = 971aaa9e70ad082cf43725f2e65bc73f4bf762459cee13167545072ec7bdcaf8
+
+Test = OrdMulMont
+A = 69d6d9f5417e87d603a3fb6acafa0d1f974abf94ca57ce58d718a0ad5d02a496
+B = 69d6d9f5417e87d603a3fb6acafa0d1f974abf94ca57ce58d718a0ad5d02a496
+Result = eb3284e5799fbe93171f08e6de9f792cd17f036b3a17671b0310e49b48e589b3
+
+Test = OrdMulMont
+A = 1c28f742c3e26e74901d0425f2eb4d5272524668d2405875b32cf6433f212900
+B = 1c28f742c3e26e74901d0425f2eb4d5272524668d2405875b32cf6433f212900
+Result = 74f70a95399b7ad061a2200fa50528d68eee4654341c8158101e1e3f8f16e642
+
+Test = OrdMulMont
+A = 026b2f69f0259d221920b2f358b378a79826f0332ee36afa257765043e3d6732
+B = 026b2f69f0259d221920b2f358b378a79826f0332ee36afa257765043e3d6732
+Result = e1e9cfa4724995bb50971ca22f3c028cd31cb51fbef8a37c31f10fd1d468f13b
+
+Test = OrdMulMont
+A = 376ed4fadcc1c6c4160a0c9c2ab7c62260367968b08d304d47c65f25625d7d60
+B = 376ed4fadcc1c6c4160a0c9c2ab7c62260367968b08d304d47c65f25625d7d60
+Result = b9ccb67f377e1278f1d2eeda26e5eed76f32406c9deed9764fc0aa346d91e02b
+
+Test = OrdMulMont
+A = 50f66867d0a4ef389678d760d2a4db886583b4c068d0e240f7ddf3472c871304
+B = 50f66867d0a4ef389678d760d2a4db886583b4c068d0e240f7ddf3472c871304
+Result = 82c3467bc5f7ca8b45f4ee61546745e2f53755a02e87f65f572418d60e471c8b
+
+Test = OrdMulMont
+A = 5b8bd82b37206d2b727f19ad2d02f63773470074dde7d43d2a77c448ddf2f978
+B = 5b8bd82b37206d2b727f19ad2d02f63773470074dde7d43d2a77c448ddf2f978
+Result = dbf3c2fc67a0688c3b5ff12cab1739d50b6093c5d98943d388652b1207e4a0f2
+
+Test = OrdMulMont
+A = bed7b3a4dada0e16984eb59ee239005ab212e5b1772cdd5d240c8ee268f65c81
+B = bed7b3a4dada0e16984eb59ee239005ab212e5b1772cdd5d240c8ee268f65c81
+Result = 9232aa2759ca9c5efbaefb0cf45cc6bc9c89def8c25e5c169fe623f30787df36
diff --git a/src/crypto/fipsmodule/ec/p256.c b/src/crypto/fipsmodule/ec/p256.c
new file mode 100644
index 0000000..af211be
--- /dev/null
+++ b/src/crypto/fipsmodule/ec/p256.c
@@ -0,0 +1,751 @@
+/* Copyright (c) 2020, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+// An implementation of the NIST P-256 elliptic curve point multiplication.
+// 256-bit Montgomery form for 64 and 32-bit. Field operations are generated by
+// Fiat, which lives in //third_party/fiat.
+
+#include <openssl/base.h>
+
+#include <openssl/bn.h>
+#include <openssl/ec.h>
+#include <openssl/err.h>
+#include <openssl/mem.h>
+
+#include <assert.h>
+#include <string.h>
+
+#include "../../internal.h"
+#include "../delocate.h"
+#include "./internal.h"
+
+#if defined(BORINGSSL_HAS_UINT128)
+#include "../../../third_party/fiat/p256_64.h"
+#elif defined(OPENSSL_64_BIT)
+#include "../../../third_party/fiat/p256_64_msvc.h"
+#else
+#include "../../../third_party/fiat/p256_32.h"
+#endif
+
+
+// utility functions, handwritten
+
+#if defined(OPENSSL_64_BIT)
+#define FIAT_P256_NLIMBS 4
+typedef uint64_t fiat_p256_limb_t;
+typedef uint64_t fiat_p256_felem[FIAT_P256_NLIMBS];
+static const fiat_p256_felem fiat_p256_one = {0x1, 0xffffffff00000000,
+ 0xffffffffffffffff, 0xfffffffe};
+#else // 64BIT; else 32BIT
+#define FIAT_P256_NLIMBS 8
+typedef uint32_t fiat_p256_limb_t;
+typedef uint32_t fiat_p256_felem[FIAT_P256_NLIMBS];
+static const fiat_p256_felem fiat_p256_one = {
+ 0x1, 0x0, 0x0, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffffffe, 0x0};
+#endif // 64BIT
+
+
+static fiat_p256_limb_t fiat_p256_nz(
+ const fiat_p256_limb_t in1[FIAT_P256_NLIMBS]) {
+ fiat_p256_limb_t ret;
+ fiat_p256_nonzero(&ret, in1);
+ return ret;
+}
+
+static void fiat_p256_copy(fiat_p256_limb_t out[FIAT_P256_NLIMBS],
+ const fiat_p256_limb_t in1[FIAT_P256_NLIMBS]) {
+ for (size_t i = 0; i < FIAT_P256_NLIMBS; i++) {
+ out[i] = in1[i];
+ }
+}
+
+static void fiat_p256_cmovznz(fiat_p256_limb_t out[FIAT_P256_NLIMBS],
+ fiat_p256_limb_t t,
+ const fiat_p256_limb_t z[FIAT_P256_NLIMBS],
+ const fiat_p256_limb_t nz[FIAT_P256_NLIMBS]) {
+ fiat_p256_selectznz(out, !!t, z, nz);
+}
+
+static void fiat_p256_from_words(fiat_p256_felem out,
+ const BN_ULONG in[32 / sizeof(BN_ULONG)]) {
+ // Typically, |BN_ULONG| and |fiat_p256_limb_t| will be the same type, but on
+ // 64-bit platforms without |uint128_t|, they are different. However, on
+ // little-endian systems, |uint64_t[4]| and |uint32_t[8]| have the same
+ // layout.
+ OPENSSL_memcpy(out, in, 32);
+}
+
+static void fiat_p256_from_generic(fiat_p256_felem out, const EC_FELEM *in) {
+ fiat_p256_from_words(out, in->words);
+}
+
+static void fiat_p256_to_generic(EC_FELEM *out, const fiat_p256_felem in) {
+ // See |fiat_p256_from_words|.
+ OPENSSL_memcpy(out->words, in, 32);
+}
+
+// fiat_p256_inv_square calculates |out| = |in|^{-2}
+//
+// Based on Fermat's Little Theorem:
+// a^p = a (mod p)
+// a^{p-1} = 1 (mod p)
+// a^{p-3} = a^{-2} (mod p)
+static void fiat_p256_inv_square(fiat_p256_felem out,
+ const fiat_p256_felem in) {
+ // This implements the addition chain described in
+ // https://briansmith.org/ecc-inversion-addition-chains-01#p256_field_inversion
+ fiat_p256_felem x2, x3, x6, x12, x15, x30, x32;
+ fiat_p256_square(x2, in); // 2^2 - 2^1
+ fiat_p256_mul(x2, x2, in); // 2^2 - 2^0
+
+ fiat_p256_square(x3, x2); // 2^3 - 2^1
+ fiat_p256_mul(x3, x3, in); // 2^3 - 2^0
+
+ fiat_p256_square(x6, x3);
+ for (int i = 1; i < 3; i++) {
+ fiat_p256_square(x6, x6);
+ } // 2^6 - 2^3
+ fiat_p256_mul(x6, x6, x3); // 2^6 - 2^0
+
+ fiat_p256_square(x12, x6);
+ for (int i = 1; i < 6; i++) {
+ fiat_p256_square(x12, x12);
+ } // 2^12 - 2^6
+ fiat_p256_mul(x12, x12, x6); // 2^12 - 2^0
+
+ fiat_p256_square(x15, x12);
+ for (int i = 1; i < 3; i++) {
+ fiat_p256_square(x15, x15);
+ } // 2^15 - 2^3
+ fiat_p256_mul(x15, x15, x3); // 2^15 - 2^0
+
+ fiat_p256_square(x30, x15);
+ for (int i = 1; i < 15; i++) {
+ fiat_p256_square(x30, x30);
+ } // 2^30 - 2^15
+ fiat_p256_mul(x30, x30, x15); // 2^30 - 2^0
+
+ fiat_p256_square(x32, x30);
+ fiat_p256_square(x32, x32); // 2^32 - 2^2
+ fiat_p256_mul(x32, x32, x2); // 2^32 - 2^0
+
+ fiat_p256_felem ret;
+ fiat_p256_square(ret, x32);
+ for (int i = 1; i < 31 + 1; i++) {
+ fiat_p256_square(ret, ret);
+ } // 2^64 - 2^32
+ fiat_p256_mul(ret, ret, in); // 2^64 - 2^32 + 2^0
+
+ for (int i = 0; i < 96 + 32; i++) {
+ fiat_p256_square(ret, ret);
+ } // 2^192 - 2^160 + 2^128
+ fiat_p256_mul(ret, ret, x32); // 2^192 - 2^160 + 2^128 + 2^32 - 2^0
+
+ for (int i = 0; i < 32; i++) {
+ fiat_p256_square(ret, ret);
+ } // 2^224 - 2^192 + 2^160 + 2^64 - 2^32
+ fiat_p256_mul(ret, ret, x32); // 2^224 - 2^192 + 2^160 + 2^64 - 2^0
+
+ for (int i = 0; i < 30; i++) {
+ fiat_p256_square(ret, ret);
+ } // 2^254 - 2^222 + 2^190 + 2^94 - 2^30
+ fiat_p256_mul(ret, ret, x30); // 2^254 - 2^222 + 2^190 + 2^94 - 2^0
+
+ fiat_p256_square(ret, ret);
+ fiat_p256_square(out, ret); // 2^256 - 2^224 + 2^192 + 2^96 - 2^2
+}
+
+// Group operations
+// ----------------
+//
+// Building on top of the field operations we have the operations on the
+// elliptic curve group itself. Points on the curve are represented in Jacobian
+// coordinates.
+//
+// Both operations were transcribed to Coq and proven to correspond to naive
+// implementations using Affine coordinates, for all suitable fields. In the
+// Coq proofs, issues of constant-time execution and memory layout (aliasing)
+// conventions were not considered. Specification of affine coordinates:
+// <https://github.com/mit-plv/fiat-crypto/blob/79f8b5f39ed609339f0233098dee1a3c4e6b3080/src/Spec/WeierstrassCurve.v#L28>
+// As a sanity check, a proof that these points form a commutative group:
+// <https://github.com/mit-plv/fiat-crypto/blob/79f8b5f39ed609339f0233098dee1a3c4e6b3080/src/Curves/Weierstrass/AffineProofs.v#L33>
+
+// fiat_p256_point_double calculates 2*(x_in, y_in, z_in)
+//
+// The method is taken from:
+// http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
+//
+// Coq transcription and correctness proof:
+// <https://github.com/mit-plv/fiat-crypto/blob/79f8b5f39ed609339f0233098dee1a3c4e6b3080/src/Curves/Weierstrass/Jacobian.v#L93>
+// <https://github.com/mit-plv/fiat-crypto/blob/79f8b5f39ed609339f0233098dee1a3c4e6b3080/src/Curves/Weierstrass/Jacobian.v#L201>
+//
+// Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed.
+// while x_out == y_in is not (maybe this works, but it's not tested).
+static void fiat_p256_point_double(fiat_p256_felem x_out, fiat_p256_felem y_out,
+ fiat_p256_felem z_out,
+ const fiat_p256_felem x_in,
+ const fiat_p256_felem y_in,
+ const fiat_p256_felem z_in) {
+ fiat_p256_felem delta, gamma, beta, ftmp, ftmp2, tmptmp, alpha, fourbeta;
+ // delta = z^2
+ fiat_p256_square(delta, z_in);
+ // gamma = y^2
+ fiat_p256_square(gamma, y_in);
+ // beta = x*gamma
+ fiat_p256_mul(beta, x_in, gamma);
+
+ // alpha = 3*(x-delta)*(x+delta)
+ fiat_p256_sub(ftmp, x_in, delta);
+ fiat_p256_add(ftmp2, x_in, delta);
+
+ fiat_p256_add(tmptmp, ftmp2, ftmp2);
+ fiat_p256_add(ftmp2, ftmp2, tmptmp);
+ fiat_p256_mul(alpha, ftmp, ftmp2);
+
+ // x' = alpha^2 - 8*beta
+ fiat_p256_square(x_out, alpha);
+ fiat_p256_add(fourbeta, beta, beta);
+ fiat_p256_add(fourbeta, fourbeta, fourbeta);
+ fiat_p256_add(tmptmp, fourbeta, fourbeta);
+ fiat_p256_sub(x_out, x_out, tmptmp);
+
+ // z' = (y + z)^2 - gamma - delta
+ fiat_p256_add(delta, gamma, delta);
+ fiat_p256_add(ftmp, y_in, z_in);
+ fiat_p256_square(z_out, ftmp);
+ fiat_p256_sub(z_out, z_out, delta);
+
+ // y' = alpha*(4*beta - x') - 8*gamma^2
+ fiat_p256_sub(y_out, fourbeta, x_out);
+ fiat_p256_add(gamma, gamma, gamma);
+ fiat_p256_square(gamma, gamma);
+ fiat_p256_mul(y_out, alpha, y_out);
+ fiat_p256_add(gamma, gamma, gamma);
+ fiat_p256_sub(y_out, y_out, gamma);
+}
+
+// fiat_p256_point_add calculates (x1, y1, z1) + (x2, y2, z2)
+//
+// The method is taken from:
+// http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl,
+// adapted for mixed addition (z2 = 1, or z2 = 0 for the point at infinity).
+//
+// Coq transcription and correctness proof:
+// <https://github.com/mit-plv/fiat-crypto/blob/79f8b5f39ed609339f0233098dee1a3c4e6b3080/src/Curves/Weierstrass/Jacobian.v#L135>
+// <https://github.com/mit-plv/fiat-crypto/blob/79f8b5f39ed609339f0233098dee1a3c4e6b3080/src/Curves/Weierstrass/Jacobian.v#L205>
+//
+// This function includes a branch for checking whether the two input points
+// are equal, (while not equal to the point at infinity). This case never
+// happens during single point multiplication, so there is no timing leak for
+// ECDH or ECDSA signing.
+static void fiat_p256_point_add(fiat_p256_felem x3, fiat_p256_felem y3,
+ fiat_p256_felem z3, const fiat_p256_felem x1,
+ const fiat_p256_felem y1,
+ const fiat_p256_felem z1, const int mixed,
+ const fiat_p256_felem x2,
+ const fiat_p256_felem y2,
+ const fiat_p256_felem z2) {
+ fiat_p256_felem x_out, y_out, z_out;
+ fiat_p256_limb_t z1nz = fiat_p256_nz(z1);
+ fiat_p256_limb_t z2nz = fiat_p256_nz(z2);
+
+ // z1z1 = z1z1 = z1**2
+ fiat_p256_felem z1z1;
+ fiat_p256_square(z1z1, z1);
+
+ fiat_p256_felem u1, s1, two_z1z2;
+ if (!mixed) {
+ // z2z2 = z2**2
+ fiat_p256_felem z2z2;
+ fiat_p256_square(z2z2, z2);
+
+ // u1 = x1*z2z2
+ fiat_p256_mul(u1, x1, z2z2);
+
+ // two_z1z2 = (z1 + z2)**2 - (z1z1 + z2z2) = 2z1z2
+ fiat_p256_add(two_z1z2, z1, z2);
+ fiat_p256_square(two_z1z2, two_z1z2);
+ fiat_p256_sub(two_z1z2, two_z1z2, z1z1);
+ fiat_p256_sub(two_z1z2, two_z1z2, z2z2);
+
+ // s1 = y1 * z2**3
+ fiat_p256_mul(s1, z2, z2z2);
+ fiat_p256_mul(s1, s1, y1);
+ } else {
+ // We'll assume z2 = 1 (special case z2 = 0 is handled later).
+
+ // u1 = x1*z2z2
+ fiat_p256_copy(u1, x1);
+ // two_z1z2 = 2z1z2
+ fiat_p256_add(two_z1z2, z1, z1);
+ // s1 = y1 * z2**3
+ fiat_p256_copy(s1, y1);
+ }
+
+ // u2 = x2*z1z1
+ fiat_p256_felem u2;
+ fiat_p256_mul(u2, x2, z1z1);
+
+ // h = u2 - u1
+ fiat_p256_felem h;
+ fiat_p256_sub(h, u2, u1);
+
+ fiat_p256_limb_t xneq = fiat_p256_nz(h);
+
+ // z_out = two_z1z2 * h
+ fiat_p256_mul(z_out, h, two_z1z2);
+
+ // z1z1z1 = z1 * z1z1
+ fiat_p256_felem z1z1z1;
+ fiat_p256_mul(z1z1z1, z1, z1z1);
+
+ // s2 = y2 * z1**3
+ fiat_p256_felem s2;
+ fiat_p256_mul(s2, y2, z1z1z1);
+
+ // r = (s2 - s1)*2
+ fiat_p256_felem r;
+ fiat_p256_sub(r, s2, s1);
+ fiat_p256_add(r, r, r);
+
+ fiat_p256_limb_t yneq = fiat_p256_nz(r);
+
+ fiat_p256_limb_t is_nontrivial_double = constant_time_is_zero_w(xneq | yneq) &
+ ~constant_time_is_zero_w(z1nz) &
+ ~constant_time_is_zero_w(z2nz);
+ if (is_nontrivial_double) {
+ fiat_p256_point_double(x3, y3, z3, x1, y1, z1);
+ return;
+ }
+
+ // I = (2h)**2
+ fiat_p256_felem i;
+ fiat_p256_add(i, h, h);
+ fiat_p256_square(i, i);
+
+ // J = h * I
+ fiat_p256_felem j;
+ fiat_p256_mul(j, h, i);
+
+ // V = U1 * I
+ fiat_p256_felem v;
+ fiat_p256_mul(v, u1, i);
+
+ // x_out = r**2 - J - 2V
+ fiat_p256_square(x_out, r);
+ fiat_p256_sub(x_out, x_out, j);
+ fiat_p256_sub(x_out, x_out, v);
+ fiat_p256_sub(x_out, x_out, v);
+
+ // y_out = r(V-x_out) - 2 * s1 * J
+ fiat_p256_sub(y_out, v, x_out);
+ fiat_p256_mul(y_out, y_out, r);
+ fiat_p256_felem s1j;
+ fiat_p256_mul(s1j, s1, j);
+ fiat_p256_sub(y_out, y_out, s1j);
+ fiat_p256_sub(y_out, y_out, s1j);
+
+ fiat_p256_cmovznz(x_out, z1nz, x2, x_out);
+ fiat_p256_cmovznz(x3, z2nz, x1, x_out);
+ fiat_p256_cmovznz(y_out, z1nz, y2, y_out);
+ fiat_p256_cmovznz(y3, z2nz, y1, y_out);
+ fiat_p256_cmovznz(z_out, z1nz, z2, z_out);
+ fiat_p256_cmovznz(z3, z2nz, z1, z_out);
+}
+
+#include "./p256_table.h"
+
+// fiat_p256_select_point_affine selects the |idx-1|th point from a
+// precomputation table and copies it to out. If |idx| is zero, the output is
+// the point at infinity.
+static void fiat_p256_select_point_affine(
+ const fiat_p256_limb_t idx, size_t size,
+ const fiat_p256_felem pre_comp[/*size*/][2], fiat_p256_felem out[3]) {
+ OPENSSL_memset(out, 0, sizeof(fiat_p256_felem) * 3);
+ for (size_t i = 0; i < size; i++) {
+ fiat_p256_limb_t mismatch = i ^ (idx - 1);
+ fiat_p256_cmovznz(out[0], mismatch, pre_comp[i][0], out[0]);
+ fiat_p256_cmovznz(out[1], mismatch, pre_comp[i][1], out[1]);
+ }
+ fiat_p256_cmovznz(out[2], idx, out[2], fiat_p256_one);
+}
+
+// fiat_p256_select_point selects the |idx|th point from a precomputation table
+// and copies it to out.
+static void fiat_p256_select_point(const fiat_p256_limb_t idx, size_t size,
+ const fiat_p256_felem pre_comp[/*size*/][3],
+ fiat_p256_felem out[3]) {
+ OPENSSL_memset(out, 0, sizeof(fiat_p256_felem) * 3);
+ for (size_t i = 0; i < size; i++) {
+ fiat_p256_limb_t mismatch = i ^ idx;
+ fiat_p256_cmovznz(out[0], mismatch, pre_comp[i][0], out[0]);
+ fiat_p256_cmovznz(out[1], mismatch, pre_comp[i][1], out[1]);
+ fiat_p256_cmovznz(out[2], mismatch, pre_comp[i][2], out[2]);
+ }
+}
+
+// fiat_p256_get_bit returns the |i|th bit in |in|.
+static crypto_word_t fiat_p256_get_bit(const EC_SCALAR *in, int i) {
+ if (i < 0 || i >= 256) {
+ return 0;
+ }
+#if defined(OPENSSL_64_BIT)
+ static_assert(sizeof(BN_ULONG) == 8, "BN_ULONG was not 64-bit");
+ return (in->words[i >> 6] >> (i & 63)) & 1;
+#else
+ static_assert(sizeof(BN_ULONG) == 4, "BN_ULONG was not 32-bit");
+ return (in->words[i >> 5] >> (i & 31)) & 1;
+#endif
+}
+
+// OPENSSL EC_METHOD FUNCTIONS
+
+// Takes the Jacobian coordinates (X, Y, Z) of a point and returns (X', Y') =
+// (X/Z^2, Y/Z^3).
+static int ec_GFp_nistp256_point_get_affine_coordinates(
+ const EC_GROUP *group, const EC_JACOBIAN *point, EC_FELEM *x_out,
+ EC_FELEM *y_out) {
+ if (ec_GFp_simple_is_at_infinity(group, point)) {
+ OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY);
+ return 0;
+ }
+
+ fiat_p256_felem z1, z2;
+ fiat_p256_from_generic(z1, &point->Z);
+ fiat_p256_inv_square(z2, z1);
+
+ if (x_out != NULL) {
+ fiat_p256_felem x;
+ fiat_p256_from_generic(x, &point->X);
+ fiat_p256_mul(x, x, z2);
+ fiat_p256_to_generic(x_out, x);
+ }
+
+ if (y_out != NULL) {
+ fiat_p256_felem y;
+ fiat_p256_from_generic(y, &point->Y);
+ fiat_p256_square(z2, z2); // z^-4
+ fiat_p256_mul(y, y, z1); // y * z
+ fiat_p256_mul(y, y, z2); // y * z^-3
+ fiat_p256_to_generic(y_out, y);
+ }
+
+ return 1;
+}
+
+static void ec_GFp_nistp256_add(const EC_GROUP *group, EC_JACOBIAN *r,
+ const EC_JACOBIAN *a, const EC_JACOBIAN *b) {
+ fiat_p256_felem x1, y1, z1, x2, y2, z2;
+ fiat_p256_from_generic(x1, &a->X);
+ fiat_p256_from_generic(y1, &a->Y);
+ fiat_p256_from_generic(z1, &a->Z);
+ fiat_p256_from_generic(x2, &b->X);
+ fiat_p256_from_generic(y2, &b->Y);
+ fiat_p256_from_generic(z2, &b->Z);
+ fiat_p256_point_add(x1, y1, z1, x1, y1, z1, 0 /* both Jacobian */, x2, y2,
+ z2);
+ fiat_p256_to_generic(&r->X, x1);
+ fiat_p256_to_generic(&r->Y, y1);
+ fiat_p256_to_generic(&r->Z, z1);
+}
+
+static void ec_GFp_nistp256_dbl(const EC_GROUP *group, EC_JACOBIAN *r,
+ const EC_JACOBIAN *a) {
+ fiat_p256_felem x, y, z;
+ fiat_p256_from_generic(x, &a->X);
+ fiat_p256_from_generic(y, &a->Y);
+ fiat_p256_from_generic(z, &a->Z);
+ fiat_p256_point_double(x, y, z, x, y, z);
+ fiat_p256_to_generic(&r->X, x);
+ fiat_p256_to_generic(&r->Y, y);
+ fiat_p256_to_generic(&r->Z, z);
+}
+
+static void ec_GFp_nistp256_point_mul(const EC_GROUP *group, EC_JACOBIAN *r,
+ const EC_JACOBIAN *p,
+ const EC_SCALAR *scalar) {
+ fiat_p256_felem p_pre_comp[17][3];
+ OPENSSL_memset(&p_pre_comp, 0, sizeof(p_pre_comp));
+ // Precompute multiples.
+ fiat_p256_from_generic(p_pre_comp[1][0], &p->X);
+ fiat_p256_from_generic(p_pre_comp[1][1], &p->Y);
+ fiat_p256_from_generic(p_pre_comp[1][2], &p->Z);
+ for (size_t j = 2; j <= 16; ++j) {
+ if (j & 1) {
+ fiat_p256_point_add(p_pre_comp[j][0], p_pre_comp[j][1], p_pre_comp[j][2],
+ p_pre_comp[1][0], p_pre_comp[1][1], p_pre_comp[1][2],
+ 0, p_pre_comp[j - 1][0], p_pre_comp[j - 1][1],
+ p_pre_comp[j - 1][2]);
+ } else {
+ fiat_p256_point_double(p_pre_comp[j][0], p_pre_comp[j][1],
+ p_pre_comp[j][2], p_pre_comp[j / 2][0],
+ p_pre_comp[j / 2][1], p_pre_comp[j / 2][2]);
+ }
+ }
+
+ // Set nq to the point at infinity.
+ fiat_p256_felem nq[3] = {{0}, {0}, {0}}, ftmp, tmp[3];
+
+ // Loop over |scalar| msb-to-lsb, incorporating |p_pre_comp| every 5th round.
+ int skip = 1; // Save two point operations in the first round.
+ for (size_t i = 255; i < 256; i--) {
+ // double
+ if (!skip) {
+ fiat_p256_point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]);
+ }
+
+ // do other additions every 5 doublings
+ if (i % 5 == 0) {
+ crypto_word_t bits = fiat_p256_get_bit(scalar, i + 4) << 5;
+ bits |= fiat_p256_get_bit(scalar, i + 3) << 4;
+ bits |= fiat_p256_get_bit(scalar, i + 2) << 3;
+ bits |= fiat_p256_get_bit(scalar, i + 1) << 2;
+ bits |= fiat_p256_get_bit(scalar, i) << 1;
+ bits |= fiat_p256_get_bit(scalar, i - 1);
+ crypto_word_t sign, digit;
+ ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
+
+ // select the point to add or subtract, in constant time.
+ fiat_p256_select_point((fiat_p256_limb_t)digit, 17,
+ (const fiat_p256_felem(*)[3])p_pre_comp, tmp);
+ fiat_p256_opp(ftmp, tmp[1]); // (X, -Y, Z) is the negative point.
+ fiat_p256_cmovznz(tmp[1], (fiat_p256_limb_t)sign, tmp[1], ftmp);
+
+ if (!skip) {
+ fiat_p256_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2],
+ 0 /* mixed */, tmp[0], tmp[1], tmp[2]);
+ } else {
+ fiat_p256_copy(nq[0], tmp[0]);
+ fiat_p256_copy(nq[1], tmp[1]);
+ fiat_p256_copy(nq[2], tmp[2]);
+ skip = 0;
+ }
+ }
+ }
+
+ fiat_p256_to_generic(&r->X, nq[0]);
+ fiat_p256_to_generic(&r->Y, nq[1]);
+ fiat_p256_to_generic(&r->Z, nq[2]);
+}
+
+static void ec_GFp_nistp256_point_mul_base(const EC_GROUP *group,
+ EC_JACOBIAN *r,
+ const EC_SCALAR *scalar) {
+ // Set nq to the point at infinity.
+ fiat_p256_felem nq[3] = {{0}, {0}, {0}}, tmp[3];
+
+ int skip = 1; // Save two point operations in the first round.
+ for (size_t i = 31; i < 32; i--) {
+ if (!skip) {
+ fiat_p256_point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]);
+ }
+
+ // First, look 32 bits upwards.
+ crypto_word_t bits = fiat_p256_get_bit(scalar, i + 224) << 3;
+ bits |= fiat_p256_get_bit(scalar, i + 160) << 2;
+ bits |= fiat_p256_get_bit(scalar, i + 96) << 1;
+ bits |= fiat_p256_get_bit(scalar, i + 32);
+ // Select the point to add, in constant time.
+ fiat_p256_select_point_affine((fiat_p256_limb_t)bits, 15,
+ fiat_p256_g_pre_comp[1], tmp);
+
+ if (!skip) {
+ fiat_p256_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2],
+ 1 /* mixed */, tmp[0], tmp[1], tmp[2]);
+ } else {
+ fiat_p256_copy(nq[0], tmp[0]);
+ fiat_p256_copy(nq[1], tmp[1]);
+ fiat_p256_copy(nq[2], tmp[2]);
+ skip = 0;
+ }
+
+ // Second, look at the current position.
+ bits = fiat_p256_get_bit(scalar, i + 192) << 3;
+ bits |= fiat_p256_get_bit(scalar, i + 128) << 2;
+ bits |= fiat_p256_get_bit(scalar, i + 64) << 1;
+ bits |= fiat_p256_get_bit(scalar, i);
+ // Select the point to add, in constant time.
+ fiat_p256_select_point_affine((fiat_p256_limb_t)bits, 15,
+ fiat_p256_g_pre_comp[0], tmp);
+ fiat_p256_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */,
+ tmp[0], tmp[1], tmp[2]);
+ }
+
+ fiat_p256_to_generic(&r->X, nq[0]);
+ fiat_p256_to_generic(&r->Y, nq[1]);
+ fiat_p256_to_generic(&r->Z, nq[2]);
+}
+
+static void ec_GFp_nistp256_point_mul_public(const EC_GROUP *group,
+ EC_JACOBIAN *r,
+ const EC_SCALAR *g_scalar,
+ const EC_JACOBIAN *p,
+ const EC_SCALAR *p_scalar) {
+#define P256_WSIZE_PUBLIC 4
+ // Precompute multiples of |p|. p_pre_comp[i] is (2*i+1) * |p|.
+ fiat_p256_felem p_pre_comp[1 << (P256_WSIZE_PUBLIC - 1)][3];
+ fiat_p256_from_generic(p_pre_comp[0][0], &p->X);
+ fiat_p256_from_generic(p_pre_comp[0][1], &p->Y);
+ fiat_p256_from_generic(p_pre_comp[0][2], &p->Z);
+ fiat_p256_felem p2[3];
+ fiat_p256_point_double(p2[0], p2[1], p2[2], p_pre_comp[0][0],
+ p_pre_comp[0][1], p_pre_comp[0][2]);
+ for (size_t i = 1; i < OPENSSL_ARRAY_SIZE(p_pre_comp); i++) {
+ fiat_p256_point_add(p_pre_comp[i][0], p_pre_comp[i][1], p_pre_comp[i][2],
+ p_pre_comp[i - 1][0], p_pre_comp[i - 1][1],
+ p_pre_comp[i - 1][2], 0 /* not mixed */, p2[0], p2[1],
+ p2[2]);
+ }
+
+ // Set up the coefficients for |p_scalar|.
+ int8_t p_wNAF[257];
+ ec_compute_wNAF(group, p_wNAF, p_scalar, 256, P256_WSIZE_PUBLIC);
+
+ // Set |ret| to the point at infinity.
+ int skip = 1; // Save some point operations.
+ fiat_p256_felem ret[3] = {{0}, {0}, {0}};
+ for (int i = 256; i >= 0; i--) {
+ if (!skip) {
+ fiat_p256_point_double(ret[0], ret[1], ret[2], ret[0], ret[1], ret[2]);
+ }
+
+ // For the |g_scalar|, we use the precomputed table without the
+ // constant-time lookup.
+ if (i <= 31) {
+ // First, look 32 bits upwards.
+ crypto_word_t bits = fiat_p256_get_bit(g_scalar, i + 224) << 3;
+ bits |= fiat_p256_get_bit(g_scalar, i + 160) << 2;
+ bits |= fiat_p256_get_bit(g_scalar, i + 96) << 1;
+ bits |= fiat_p256_get_bit(g_scalar, i + 32);
+ if (bits != 0) {
+ size_t index = (size_t)(bits - 1);
+ fiat_p256_point_add(ret[0], ret[1], ret[2], ret[0], ret[1], ret[2],
+ 1 /* mixed */, fiat_p256_g_pre_comp[1][index][0],
+ fiat_p256_g_pre_comp[1][index][1],
+ fiat_p256_one);
+ skip = 0;
+ }
+
+ // Second, look at the current position.
+ bits = fiat_p256_get_bit(g_scalar, i + 192) << 3;
+ bits |= fiat_p256_get_bit(g_scalar, i + 128) << 2;
+ bits |= fiat_p256_get_bit(g_scalar, i + 64) << 1;
+ bits |= fiat_p256_get_bit(g_scalar, i);
+ if (bits != 0) {
+ size_t index = (size_t)(bits - 1);
+ fiat_p256_point_add(ret[0], ret[1], ret[2], ret[0], ret[1], ret[2],
+ 1 /* mixed */, fiat_p256_g_pre_comp[0][index][0],
+ fiat_p256_g_pre_comp[0][index][1],
+ fiat_p256_one);
+ skip = 0;
+ }
+ }
+
+ int digit = p_wNAF[i];
+ if (digit != 0) {
+ assert(digit & 1);
+ size_t idx = (size_t)(digit < 0 ? (-digit) >> 1 : digit >> 1);
+ fiat_p256_felem *y = &p_pre_comp[idx][1], tmp;
+ if (digit < 0) {
+ fiat_p256_opp(tmp, p_pre_comp[idx][1]);
+ y = &tmp;
+ }
+ if (!skip) {
+ fiat_p256_point_add(ret[0], ret[1], ret[2], ret[0], ret[1], ret[2],
+ 0 /* not mixed */, p_pre_comp[idx][0], *y,
+ p_pre_comp[idx][2]);
+ } else {
+ fiat_p256_copy(ret[0], p_pre_comp[idx][0]);
+ fiat_p256_copy(ret[1], *y);
+ fiat_p256_copy(ret[2], p_pre_comp[idx][2]);
+ skip = 0;
+ }
+ }
+ }
+
+ fiat_p256_to_generic(&r->X, ret[0]);
+ fiat_p256_to_generic(&r->Y, ret[1]);
+ fiat_p256_to_generic(&r->Z, ret[2]);
+}
+
+static int ec_GFp_nistp256_cmp_x_coordinate(const EC_GROUP *group,
+ const EC_JACOBIAN *p,
+ const EC_SCALAR *r) {
+ if (ec_GFp_simple_is_at_infinity(group, p)) {
+ return 0;
+ }
+
+ // We wish to compare X/Z^2 with r. This is equivalent to comparing X with
+ // r*Z^2. Note that X and Z are represented in Montgomery form, while r is
+ // not.
+ fiat_p256_felem Z2_mont;
+ fiat_p256_from_generic(Z2_mont, &p->Z);
+ fiat_p256_mul(Z2_mont, Z2_mont, Z2_mont);
+
+ fiat_p256_felem r_Z2;
+ fiat_p256_from_words(r_Z2, r->words); // r < order < p, so this is valid.
+ fiat_p256_mul(r_Z2, r_Z2, Z2_mont);
+
+ fiat_p256_felem X;
+ fiat_p256_from_generic(X, &p->X);
+ fiat_p256_from_montgomery(X, X);
+
+ if (OPENSSL_memcmp(&r_Z2, &X, sizeof(r_Z2)) == 0) {
+ return 1;
+ }
+
+ // During signing the x coefficient is reduced modulo the group order.
+ // Therefore there is a small possibility, less than 1/2^128, that group_order
+ // < p.x < P. in that case we need not only to compare against |r| but also to
+ // compare against r+group_order.
+ assert(group->field.width == group->order.width);
+ if (bn_less_than_words(r->words, group->field_minus_order.words,
+ group->field.width)) {
+ // We can ignore the carry because: r + group_order < p < 2^256.
+ EC_FELEM tmp;
+ bn_add_words(tmp.words, r->words, group->order.d, group->order.width);
+ fiat_p256_from_generic(r_Z2, &tmp);
+ fiat_p256_mul(r_Z2, r_Z2, Z2_mont);
+ if (OPENSSL_memcmp(&r_Z2, &X, sizeof(r_Z2)) == 0) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+DEFINE_METHOD_FUNCTION(EC_METHOD, EC_GFp_nistp256_method) {
+ out->group_init = ec_GFp_mont_group_init;
+ out->group_finish = ec_GFp_mont_group_finish;
+ out->group_set_curve = ec_GFp_mont_group_set_curve;
+ out->point_get_affine_coordinates =
+ ec_GFp_nistp256_point_get_affine_coordinates;
+ out->add = ec_GFp_nistp256_add;
+ out->dbl = ec_GFp_nistp256_dbl;
+ out->mul = ec_GFp_nistp256_point_mul;
+ out->mul_base = ec_GFp_nistp256_point_mul_base;
+ out->mul_public = ec_GFp_nistp256_point_mul_public;
+ out->felem_mul = ec_GFp_mont_felem_mul;
+ out->felem_sqr = ec_GFp_mont_felem_sqr;
+ out->felem_to_bytes = ec_GFp_mont_felem_to_bytes;
+ out->felem_from_bytes = ec_GFp_mont_felem_from_bytes;
+ out->felem_reduce = ec_GFp_mont_felem_reduce;
+ // TODO(davidben): This should use the specialized field arithmetic
+ // implementation, rather than the generic one.
+ out->felem_exp = ec_GFp_mont_felem_exp;
+ out->scalar_inv0_montgomery = ec_simple_scalar_inv0_montgomery;
+ out->scalar_to_montgomery_inv_vartime =
+ ec_simple_scalar_to_montgomery_inv_vartime;
+ out->cmp_x_coordinate = ec_GFp_nistp256_cmp_x_coordinate;
+}
diff --git a/src/crypto/fipsmodule/ec/p256_table.h b/src/crypto/fipsmodule/ec/p256_table.h
new file mode 100644
index 0000000..d823d37
--- /dev/null
+++ b/src/crypto/fipsmodule/ec/p256_table.h
@@ -0,0 +1,297 @@
+/* Copyright (c) 2020, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+// This file is generated by make_tables.go.
+
+// Base point pre computation
+// --------------------------
+//
+// Two different sorts of precomputed tables are used in the following code.
+// Each contain various points on the curve, where each point is three field
+// elements (x, y, z).
+//
+// For the base point table, z is usually 1 (0 for the point at infinity).
+// This table has 2 * 16 elements, starting with the following:
+// index | bits | point
+// ------+---------+------------------------------
+// 0 | 0 0 0 0 | 0G
+// 1 | 0 0 0 1 | 1G
+// 2 | 0 0 1 0 | 2^64G
+// 3 | 0 0 1 1 | (2^64 + 1)G
+// 4 | 0 1 0 0 | 2^128G
+// 5 | 0 1 0 1 | (2^128 + 1)G
+// 6 | 0 1 1 0 | (2^128 + 2^64)G
+// 7 | 0 1 1 1 | (2^128 + 2^64 + 1)G
+// 8 | 1 0 0 0 | 2^192G
+// 9 | 1 0 0 1 | (2^192 + 1)G
+// 10 | 1 0 1 0 | (2^192 + 2^64)G
+// 11 | 1 0 1 1 | (2^192 + 2^64 + 1)G
+// 12 | 1 1 0 0 | (2^192 + 2^128)G
+// 13 | 1 1 0 1 | (2^192 + 2^128 + 1)G
+// 14 | 1 1 1 0 | (2^192 + 2^128 + 2^64)G
+// 15 | 1 1 1 1 | (2^192 + 2^128 + 2^64 + 1)G
+// followed by a copy of this with each element multiplied by 2^32.
+//
+// The reason for this is so that we can clock bits into four different
+// locations when doing simple scalar multiplies against the base point,
+// and then another four locations using the second 16 elements.
+//
+// Tables for other points have table[i] = iG for i in 0 .. 16.
+
+// fiat_p256_g_pre_comp is the table of precomputed base points
+#if defined(OPENSSL_64_BIT)
+static const fiat_p256_felem fiat_p256_g_pre_comp[2][15][2] = {
+ {{{0x79e730d418a9143c, 0x75ba95fc5fedb601, 0x79fb732b77622510,
+ 0x18905f76a53755c6},
+ {0xddf25357ce95560a, 0x8b4ab8e4ba19e45c, 0xd2e88688dd21f325,
+ 0x8571ff1825885d85}},
+ {{0x4f922fc516a0d2bb, 0x0d5cc16c1a623499, 0x9241cf3a57c62c8b,
+ 0x2f5e6961fd1b667f},
+ {0x5c15c70bf5a01797, 0x3d20b44d60956192, 0x04911b37071fdb52,
+ 0xf648f9168d6f0f7b}},
+ {{0x9e566847e137bbbc, 0xe434469e8a6a0bec, 0xb1c4276179d73463,
+ 0x5abe0285133d0015},
+ {0x92aa837cc04c7dab, 0x573d9f4c43260c07, 0x0c93156278e6cc37,
+ 0x94bb725b6b6f7383}},
+ {{0x62a8c244bfe20925, 0x91c19ac38fdce867, 0x5a96a5d5dd387063,
+ 0x61d587d421d324f6},
+ {0xe87673a2a37173ea, 0x2384800853778b65, 0x10f8441e05bab43e,
+ 0xfa11fe124621efbe}},
+ {{0x1c891f2b2cb19ffd, 0x01ba8d5bb1923c23, 0xb6d03d678ac5ca8e,
+ 0x586eb04c1f13bedc},
+ {0x0c35c6e527e8ed09, 0x1e81a33c1819ede2, 0x278fd6c056c652fa,
+ 0x19d5ac0870864f11}},
+ {{0x62577734d2b533d5, 0x673b8af6a1bdddc0, 0x577e7c9aa79ec293,
+ 0xbb6de651c3b266b1},
+ {0xe7e9303ab65259b3, 0xd6a0afd3d03a7480, 0xc5ac83d19b3cfc27,
+ 0x60b4619a5d18b99b}},
+ {{0xbd6a38e11ae5aa1c, 0xb8b7652b49e73658, 0x0b130014ee5f87ed,
+ 0x9d0f27b2aeebffcd},
+ {0xca9246317a730a55, 0x9c955b2fddbbc83a, 0x07c1dfe0ac019a71,
+ 0x244a566d356ec48d}},
+ {{0x56f8410ef4f8b16a, 0x97241afec47b266a, 0x0a406b8e6d9c87c1,
+ 0x803f3e02cd42ab1b},
+ {0x7f0309a804dbec69, 0xa83b85f73bbad05f, 0xc6097273ad8e197f,
+ 0xc097440e5067adc1}},
+ {{0x846a56f2c379ab34, 0xa8ee068b841df8d1, 0x20314459176c68ef,
+ 0xf1af32d5915f1f30},
+ {0x99c375315d75bd50, 0x837cffbaf72f67bc, 0x0613a41848d7723f,
+ 0x23d0f130e2d41c8b}},
+ {{0xed93e225d5be5a2b, 0x6fe799835934f3c6, 0x4314092622626ffc,
+ 0x50bbb4d97990216a},
+ {0x378191c6e57ec63e, 0x65422c40181dcdb2, 0x41a8099b0236e0f6,
+ 0x2b10011801fe49c3}},
+ {{0xfc68b5c59b391593, 0xc385f5a2598270fc, 0x7144f3aad19adcbb,
+ 0xdd55899983fbae0c},
+ {0x93b88b8e74b82ff4, 0xd2e03c4071e734c9, 0x9a7a9eaf43c0322a,
+ 0xe6e4c551149d6041}},
+ {{0x5fe14bfe80ec21fe, 0xf6ce116ac255be82, 0x98bc5a072f4a5d67,
+ 0xfad27148db7e63af},
+ {0x90c0b6ac29ab05b3, 0x37a9a83c4e251ae6, 0x0a7dc875c2aade7d,
+ 0x77387de39f0e1a84}},
+ {{0x1e9ecc49a56c0dd7, 0xa5cffcd846086c74, 0x8f7a1408f505aece,
+ 0xb37b85c0bef0c47e},
+ {0x3596b6e4cc0e6a8f, 0xfd6d4bbf6b388f23, 0xaba453fac39cef4e,
+ 0x9c135ac8f9f628d5}},
+ {{0x0a1c729495c8f8be, 0x2961c4803bf362bf, 0x9e418403df63d4ac,
+ 0xc109f9cb91ece900},
+ {0xc2d095d058945705, 0xb9083d96ddeb85c0, 0x84692b8d7a40449b,
+ 0x9bc3344f2eee1ee1}},
+ {{0x0d5ae35642913074, 0x55491b2748a542b1, 0x469ca665b310732a,
+ 0x29591d525f1a4cc1},
+ {0xe76f5b6bb84f983f, 0xbe7eef419f5f84e1, 0x1200d49680baa189,
+ 0x6376551f18ef332c}}},
+ {{{0x202886024147519a, 0xd0981eac26b372f0, 0xa9d4a7caa785ebc8,
+ 0xd953c50ddbdf58e9},
+ {0x9d6361ccfd590f8f, 0x72e9626b44e6c917, 0x7fd9611022eb64cf,
+ 0x863ebb7e9eb288f3}},
+ {{0x4fe7ee31b0e63d34, 0xf4600572a9e54fab, 0xc0493334d5e7b5a4,
+ 0x8589fb9206d54831},
+ {0xaa70f5cc6583553a, 0x0879094ae25649e5, 0xcc90450710044652,
+ 0xebb0696d02541c4f}},
+ {{0xabbaa0c03b89da99, 0xa6f2d79eb8284022, 0x27847862b81c05e8,
+ 0x337a4b5905e54d63},
+ {0x3c67500d21f7794a, 0x207005b77d6d7f61, 0x0a5a378104cfd6e8,
+ 0x0d65e0d5f4c2fbd6}},
+ {{0xd433e50f6d3549cf, 0x6f33696ffacd665e, 0x695bfdacce11fcb4,
+ 0x810ee252af7c9860},
+ {0x65450fe17159bb2c, 0xf7dfbebe758b357b, 0x2b057e74d69fea72,
+ 0xd485717a92731745}},
+ {{0xce1f69bbe83f7669, 0x09f8ae8272877d6b, 0x9548ae543244278d,
+ 0x207755dee3c2c19c},
+ {0x87bd61d96fef1945, 0x18813cefb12d28c3, 0x9fbcd1d672df64aa,
+ 0x48dc5ee57154b00d}},
+ {{0xef0f469ef49a3154, 0x3e85a5956e2b2e9a, 0x45aaec1eaa924a9c,
+ 0xaa12dfc8a09e4719},
+ {0x26f272274df69f1d, 0xe0e4c82ca2ff5e73, 0xb9d8ce73b7a9dd44,
+ 0x6c036e73e48ca901}},
+ {{0xe1e421e1a47153f0, 0xb86c3b79920418c9, 0x93bdce87705d7672,
+ 0xf25ae793cab79a77},
+ {0x1f3194a36d869d0c, 0x9d55c8824986c264, 0x49fb5ea3096e945e,
+ 0x39b8e65313db0a3e}},
+ {{0xe3417bc035d0b34a, 0x440b386b8327c0a7, 0x8fb7262dac0362d1,
+ 0x2c41114ce0cdf943},
+ {0x2ba5cef1ad95a0b1, 0xc09b37a867d54362, 0x26d6cdd201e486c9,
+ 0x20477abf42ff9297}},
+ {{0x0f121b41bc0a67d2, 0x62d4760a444d248a, 0x0e044f1d659b4737,
+ 0x08fde365250bb4a8},
+ {0xaceec3da848bf287, 0xc2a62182d3369d6e, 0x3582dfdc92449482,
+ 0x2f7e2fd2565d6cd7}},
+ {{0x0a0122b5178a876b, 0x51ff96ff085104b4, 0x050b31ab14f29f76,
+ 0x84abb28b5f87d4e6},
+ {0xd5ed439f8270790a, 0x2d6cb59d85e3f46b, 0x75f55c1b6c1e2212,
+ 0xe5436f6717655640}},
+ {{0xc2965ecc9aeb596d, 0x01ea03e7023c92b4, 0x4704b4b62e013961,
+ 0x0ca8fd3f905ea367},
+ {0x92523a42551b2b61, 0x1eb7a89c390fcd06, 0xe7f1d2be0392a63e,
+ 0x96dca2644ddb0c33}},
+ {{0x231c210e15339848, 0xe87a28e870778c8d, 0x9d1de6616956e170,
+ 0x4ac3c9382bb09c0b},
+ {0x19be05516998987d, 0x8b2376c4ae09f4d6, 0x1de0b7651a3f933d,
+ 0x380d94c7e39705f4}},
+ {{0x3685954b8c31c31d, 0x68533d005bf21a0c, 0x0bd7626e75c79ec9,
+ 0xca17754742c69d54},
+ {0xcc6edafff6d2dbb2, 0xfd0d8cbd174a9d18, 0x875e8793aa4578e8,
+ 0xa976a7139cab2ce6}},
+ {{0xce37ab11b43ea1db, 0x0a7ff1a95259d292, 0x851b02218f84f186,
+ 0xa7222beadefaad13},
+ {0xa2ac78ec2b0a9144, 0x5a024051f2fa59c5, 0x91d1eca56147ce38,
+ 0xbe94d523bc2ac690}},
+ {{0x2d8daefd79ec1a0f, 0x3bbcd6fdceb39c97, 0xf5575ffc58f61a95,
+ 0xdbd986c4adf7b420},
+ {0x81aa881415f39eb7, 0x6ee2fcf5b98d976c, 0x5465475dcf2f717d,
+ 0x8e24d3c46860bbd0}}}};
+#else
+static const fiat_p256_felem fiat_p256_g_pre_comp[2][15][2] = {
+ {{{0x18a9143c, 0x79e730d4, 0x5fedb601, 0x75ba95fc, 0x77622510, 0x79fb732b,
+ 0xa53755c6, 0x18905f76},
+ {0xce95560a, 0xddf25357, 0xba19e45c, 0x8b4ab8e4, 0xdd21f325, 0xd2e88688,
+ 0x25885d85, 0x8571ff18}},
+ {{0x16a0d2bb, 0x4f922fc5, 0x1a623499, 0x0d5cc16c, 0x57c62c8b, 0x9241cf3a,
+ 0xfd1b667f, 0x2f5e6961},
+ {0xf5a01797, 0x5c15c70b, 0x60956192, 0x3d20b44d, 0x071fdb52, 0x04911b37,
+ 0x8d6f0f7b, 0xf648f916}},
+ {{0xe137bbbc, 0x9e566847, 0x8a6a0bec, 0xe434469e, 0x79d73463, 0xb1c42761,
+ 0x133d0015, 0x5abe0285},
+ {0xc04c7dab, 0x92aa837c, 0x43260c07, 0x573d9f4c, 0x78e6cc37, 0x0c931562,
+ 0x6b6f7383, 0x94bb725b}},
+ {{0xbfe20925, 0x62a8c244, 0x8fdce867, 0x91c19ac3, 0xdd387063, 0x5a96a5d5,
+ 0x21d324f6, 0x61d587d4},
+ {0xa37173ea, 0xe87673a2, 0x53778b65, 0x23848008, 0x05bab43e, 0x10f8441e,
+ 0x4621efbe, 0xfa11fe12}},
+ {{0x2cb19ffd, 0x1c891f2b, 0xb1923c23, 0x01ba8d5b, 0x8ac5ca8e, 0xb6d03d67,
+ 0x1f13bedc, 0x586eb04c},
+ {0x27e8ed09, 0x0c35c6e5, 0x1819ede2, 0x1e81a33c, 0x56c652fa, 0x278fd6c0,
+ 0x70864f11, 0x19d5ac08}},
+ {{0xd2b533d5, 0x62577734, 0xa1bdddc0, 0x673b8af6, 0xa79ec293, 0x577e7c9a,
+ 0xc3b266b1, 0xbb6de651},
+ {0xb65259b3, 0xe7e9303a, 0xd03a7480, 0xd6a0afd3, 0x9b3cfc27, 0xc5ac83d1,
+ 0x5d18b99b, 0x60b4619a}},
+ {{0x1ae5aa1c, 0xbd6a38e1, 0x49e73658, 0xb8b7652b, 0xee5f87ed, 0x0b130014,
+ 0xaeebffcd, 0x9d0f27b2},
+ {0x7a730a55, 0xca924631, 0xddbbc83a, 0x9c955b2f, 0xac019a71, 0x07c1dfe0,
+ 0x356ec48d, 0x244a566d}},
+ {{0xf4f8b16a, 0x56f8410e, 0xc47b266a, 0x97241afe, 0x6d9c87c1, 0x0a406b8e,
+ 0xcd42ab1b, 0x803f3e02},
+ {0x04dbec69, 0x7f0309a8, 0x3bbad05f, 0xa83b85f7, 0xad8e197f, 0xc6097273,
+ 0x5067adc1, 0xc097440e}},
+ {{0xc379ab34, 0x846a56f2, 0x841df8d1, 0xa8ee068b, 0x176c68ef, 0x20314459,
+ 0x915f1f30, 0xf1af32d5},
+ {0x5d75bd50, 0x99c37531, 0xf72f67bc, 0x837cffba, 0x48d7723f, 0x0613a418,
+ 0xe2d41c8b, 0x23d0f130}},
+ {{0xd5be5a2b, 0xed93e225, 0x5934f3c6, 0x6fe79983, 0x22626ffc, 0x43140926,
+ 0x7990216a, 0x50bbb4d9},
+ {0xe57ec63e, 0x378191c6, 0x181dcdb2, 0x65422c40, 0x0236e0f6, 0x41a8099b,
+ 0x01fe49c3, 0x2b100118}},
+ {{0x9b391593, 0xfc68b5c5, 0x598270fc, 0xc385f5a2, 0xd19adcbb, 0x7144f3aa,
+ 0x83fbae0c, 0xdd558999},
+ {0x74b82ff4, 0x93b88b8e, 0x71e734c9, 0xd2e03c40, 0x43c0322a, 0x9a7a9eaf,
+ 0x149d6041, 0xe6e4c551}},
+ {{0x80ec21fe, 0x5fe14bfe, 0xc255be82, 0xf6ce116a, 0x2f4a5d67, 0x98bc5a07,
+ 0xdb7e63af, 0xfad27148},
+ {0x29ab05b3, 0x90c0b6ac, 0x4e251ae6, 0x37a9a83c, 0xc2aade7d, 0x0a7dc875,
+ 0x9f0e1a84, 0x77387de3}},
+ {{0xa56c0dd7, 0x1e9ecc49, 0x46086c74, 0xa5cffcd8, 0xf505aece, 0x8f7a1408,
+ 0xbef0c47e, 0xb37b85c0},
+ {0xcc0e6a8f, 0x3596b6e4, 0x6b388f23, 0xfd6d4bbf, 0xc39cef4e, 0xaba453fa,
+ 0xf9f628d5, 0x9c135ac8}},
+ {{0x95c8f8be, 0x0a1c7294, 0x3bf362bf, 0x2961c480, 0xdf63d4ac, 0x9e418403,
+ 0x91ece900, 0xc109f9cb},
+ {0x58945705, 0xc2d095d0, 0xddeb85c0, 0xb9083d96, 0x7a40449b, 0x84692b8d,
+ 0x2eee1ee1, 0x9bc3344f}},
+ {{0x42913074, 0x0d5ae356, 0x48a542b1, 0x55491b27, 0xb310732a, 0x469ca665,
+ 0x5f1a4cc1, 0x29591d52},
+ {0xb84f983f, 0xe76f5b6b, 0x9f5f84e1, 0xbe7eef41, 0x80baa189, 0x1200d496,
+ 0x18ef332c, 0x6376551f}}},
+ {{{0x4147519a, 0x20288602, 0x26b372f0, 0xd0981eac, 0xa785ebc8, 0xa9d4a7ca,
+ 0xdbdf58e9, 0xd953c50d},
+ {0xfd590f8f, 0x9d6361cc, 0x44e6c917, 0x72e9626b, 0x22eb64cf, 0x7fd96110,
+ 0x9eb288f3, 0x863ebb7e}},
+ {{0xb0e63d34, 0x4fe7ee31, 0xa9e54fab, 0xf4600572, 0xd5e7b5a4, 0xc0493334,
+ 0x06d54831, 0x8589fb92},
+ {0x6583553a, 0xaa70f5cc, 0xe25649e5, 0x0879094a, 0x10044652, 0xcc904507,
+ 0x02541c4f, 0xebb0696d}},
+ {{0x3b89da99, 0xabbaa0c0, 0xb8284022, 0xa6f2d79e, 0xb81c05e8, 0x27847862,
+ 0x05e54d63, 0x337a4b59},
+ {0x21f7794a, 0x3c67500d, 0x7d6d7f61, 0x207005b7, 0x04cfd6e8, 0x0a5a3781,
+ 0xf4c2fbd6, 0x0d65e0d5}},
+ {{0x6d3549cf, 0xd433e50f, 0xfacd665e, 0x6f33696f, 0xce11fcb4, 0x695bfdac,
+ 0xaf7c9860, 0x810ee252},
+ {0x7159bb2c, 0x65450fe1, 0x758b357b, 0xf7dfbebe, 0xd69fea72, 0x2b057e74,
+ 0x92731745, 0xd485717a}},
+ {{0xe83f7669, 0xce1f69bb, 0x72877d6b, 0x09f8ae82, 0x3244278d, 0x9548ae54,
+ 0xe3c2c19c, 0x207755de},
+ {0x6fef1945, 0x87bd61d9, 0xb12d28c3, 0x18813cef, 0x72df64aa, 0x9fbcd1d6,
+ 0x7154b00d, 0x48dc5ee5}},
+ {{0xf49a3154, 0xef0f469e, 0x6e2b2e9a, 0x3e85a595, 0xaa924a9c, 0x45aaec1e,
+ 0xa09e4719, 0xaa12dfc8},
+ {0x4df69f1d, 0x26f27227, 0xa2ff5e73, 0xe0e4c82c, 0xb7a9dd44, 0xb9d8ce73,
+ 0xe48ca901, 0x6c036e73}},
+ {{0xa47153f0, 0xe1e421e1, 0x920418c9, 0xb86c3b79, 0x705d7672, 0x93bdce87,
+ 0xcab79a77, 0xf25ae793},
+ {0x6d869d0c, 0x1f3194a3, 0x4986c264, 0x9d55c882, 0x096e945e, 0x49fb5ea3,
+ 0x13db0a3e, 0x39b8e653}},
+ {{0x35d0b34a, 0xe3417bc0, 0x8327c0a7, 0x440b386b, 0xac0362d1, 0x8fb7262d,
+ 0xe0cdf943, 0x2c41114c},
+ {0xad95a0b1, 0x2ba5cef1, 0x67d54362, 0xc09b37a8, 0x01e486c9, 0x26d6cdd2,
+ 0x42ff9297, 0x20477abf}},
+ {{0xbc0a67d2, 0x0f121b41, 0x444d248a, 0x62d4760a, 0x659b4737, 0x0e044f1d,
+ 0x250bb4a8, 0x08fde365},
+ {0x848bf287, 0xaceec3da, 0xd3369d6e, 0xc2a62182, 0x92449482, 0x3582dfdc,
+ 0x565d6cd7, 0x2f7e2fd2}},
+ {{0x178a876b, 0x0a0122b5, 0x085104b4, 0x51ff96ff, 0x14f29f76, 0x050b31ab,
+ 0x5f87d4e6, 0x84abb28b},
+ {0x8270790a, 0xd5ed439f, 0x85e3f46b, 0x2d6cb59d, 0x6c1e2212, 0x75f55c1b,
+ 0x17655640, 0xe5436f67}},
+ {{0x9aeb596d, 0xc2965ecc, 0x023c92b4, 0x01ea03e7, 0x2e013961, 0x4704b4b6,
+ 0x905ea367, 0x0ca8fd3f},
+ {0x551b2b61, 0x92523a42, 0x390fcd06, 0x1eb7a89c, 0x0392a63e, 0xe7f1d2be,
+ 0x4ddb0c33, 0x96dca264}},
+ {{0x15339848, 0x231c210e, 0x70778c8d, 0xe87a28e8, 0x6956e170, 0x9d1de661,
+ 0x2bb09c0b, 0x4ac3c938},
+ {0x6998987d, 0x19be0551, 0xae09f4d6, 0x8b2376c4, 0x1a3f933d, 0x1de0b765,
+ 0xe39705f4, 0x380d94c7}},
+ {{0x8c31c31d, 0x3685954b, 0x5bf21a0c, 0x68533d00, 0x75c79ec9, 0x0bd7626e,
+ 0x42c69d54, 0xca177547},
+ {0xf6d2dbb2, 0xcc6edaff, 0x174a9d18, 0xfd0d8cbd, 0xaa4578e8, 0x875e8793,
+ 0x9cab2ce6, 0xa976a713}},
+ {{0xb43ea1db, 0xce37ab11, 0x5259d292, 0x0a7ff1a9, 0x8f84f186, 0x851b0221,
+ 0xdefaad13, 0xa7222bea},
+ {0x2b0a9144, 0xa2ac78ec, 0xf2fa59c5, 0x5a024051, 0x6147ce38, 0x91d1eca5,
+ 0xbc2ac690, 0xbe94d523}},
+ {{0x79ec1a0f, 0x2d8daefd, 0xceb39c97, 0x3bbcd6fd, 0x58f61a95, 0xf5575ffc,
+ 0xadf7b420, 0xdbd986c4},
+ {0x15f39eb7, 0x81aa8814, 0xb98d976c, 0x6ee2fcf5, 0xcf2f717d, 0x5465475d,
+ 0x6860bbd0, 0x8e24d3c4}}}};
+#endif
diff --git a/src/crypto/fipsmodule/ec/scalar.c b/src/crypto/fipsmodule/ec/scalar.c
new file mode 100644
index 0000000..036049e
--- /dev/null
+++ b/src/crypto/fipsmodule/ec/scalar.c
@@ -0,0 +1,169 @@
+/* Copyright (c) 2018, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <openssl/ec.h>
+#include <openssl/err.h>
+#include <openssl/mem.h>
+
+#include "internal.h"
+#include "../bn/internal.h"
+#include "../../internal.h"
+
+
+int ec_bignum_to_scalar(const EC_GROUP *group, EC_SCALAR *out,
+ const BIGNUM *in) {
+ if (!bn_copy_words(out->words, group->order.width, in) ||
+ !bn_less_than_words(out->words, group->order.d, group->order.width)) {
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_SCALAR);
+ return 0;
+ }
+ return 1;
+}
+
+int ec_scalar_equal_vartime(const EC_GROUP *group, const EC_SCALAR *a,
+ const EC_SCALAR *b) {
+ return OPENSSL_memcmp(a->words, b->words,
+ group->order.width * sizeof(BN_ULONG)) == 0;
+}
+
+int ec_scalar_is_zero(const EC_GROUP *group, const EC_SCALAR *a) {
+ BN_ULONG mask = 0;
+ for (int i = 0; i < group->order.width; i++) {
+ mask |= a->words[i];
+ }
+ return mask == 0;
+}
+
+int ec_random_nonzero_scalar(const EC_GROUP *group, EC_SCALAR *out,
+ const uint8_t additional_data[32]) {
+ return bn_rand_range_words(out->words, 1, group->order.d, group->order.width,
+ additional_data);
+}
+
+void ec_scalar_to_bytes(const EC_GROUP *group, uint8_t *out, size_t *out_len,
+ const EC_SCALAR *in) {
+ size_t len = BN_num_bytes(&group->order);
+ bn_words_to_big_endian(out, len, in->words, group->order.width);
+ *out_len = len;
+}
+
+int ec_scalar_from_bytes(const EC_GROUP *group, EC_SCALAR *out,
+ const uint8_t *in, size_t len) {
+ if (len != BN_num_bytes(&group->order)) {
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_SCALAR);
+ return 0;
+ }
+
+ bn_big_endian_to_words(out->words, group->order.width, in, len);
+
+ if (!bn_less_than_words(out->words, group->order.d, group->order.width)) {
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_SCALAR);
+ return 0;
+ }
+
+ return 1;
+}
+
+void ec_scalar_reduce(const EC_GROUP *group, EC_SCALAR *out,
+ const BN_ULONG *words, size_t num) {
+ // Convert "from" Montgomery form so the value is reduced modulo the order.
+ bn_from_montgomery_small(out->words, group->order.width, words, num,
+ group->order_mont);
+ // Convert "to" Montgomery form to remove the R^-1 factor added.
+ ec_scalar_to_montgomery(group, out, out);
+}
+
+void ec_scalar_add(const EC_GROUP *group, EC_SCALAR *r, const EC_SCALAR *a,
+ const EC_SCALAR *b) {
+ const BIGNUM *order = &group->order;
+ BN_ULONG tmp[EC_MAX_WORDS];
+ bn_mod_add_words(r->words, a->words, b->words, order->d, tmp, order->width);
+ OPENSSL_cleanse(tmp, sizeof(tmp));
+}
+
+void ec_scalar_sub(const EC_GROUP *group, EC_SCALAR *r, const EC_SCALAR *a,
+ const EC_SCALAR *b) {
+ const BIGNUM *order = &group->order;
+ BN_ULONG tmp[EC_MAX_WORDS];
+ bn_mod_sub_words(r->words, a->words, b->words, order->d, tmp, order->width);
+ OPENSSL_cleanse(tmp, sizeof(tmp));
+}
+
+void ec_scalar_neg(const EC_GROUP *group, EC_SCALAR *r, const EC_SCALAR *a) {
+ EC_SCALAR zero;
+ OPENSSL_memset(&zero, 0, sizeof(EC_SCALAR));
+ ec_scalar_sub(group, r, &zero, a);
+}
+
+void ec_scalar_select(const EC_GROUP *group, EC_SCALAR *out, BN_ULONG mask,
+ const EC_SCALAR *a, const EC_SCALAR *b) {
+ const BIGNUM *order = &group->order;
+ bn_select_words(out->words, mask, a->words, b->words, order->width);
+}
+
+void ec_scalar_to_montgomery(const EC_GROUP *group, EC_SCALAR *r,
+ const EC_SCALAR *a) {
+ const BIGNUM *order = &group->order;
+ bn_to_montgomery_small(r->words, a->words, order->width, group->order_mont);
+}
+
+void ec_scalar_from_montgomery(const EC_GROUP *group, EC_SCALAR *r,
+ const EC_SCALAR *a) {
+ const BIGNUM *order = &group->order;
+ bn_from_montgomery_small(r->words, order->width, a->words, order->width,
+ group->order_mont);
+}
+
+void ec_scalar_mul_montgomery(const EC_GROUP *group, EC_SCALAR *r,
+ const EC_SCALAR *a, const EC_SCALAR *b) {
+ const BIGNUM *order = &group->order;
+ bn_mod_mul_montgomery_small(r->words, a->words, b->words, order->width,
+ group->order_mont);
+}
+
+void ec_simple_scalar_inv0_montgomery(const EC_GROUP *group, EC_SCALAR *r,
+ const EC_SCALAR *a) {
+ const BIGNUM *order = &group->order;
+ bn_mod_inverse0_prime_mont_small(r->words, a->words, order->width,
+ group->order_mont);
+}
+
+int ec_simple_scalar_to_montgomery_inv_vartime(const EC_GROUP *group,
+ EC_SCALAR *r,
+ const EC_SCALAR *a) {
+ if (ec_scalar_is_zero(group, a)) {
+ return 0;
+ }
+
+ // This implementation (in fact) runs in constant time,
+ // even though for this interface it is not mandatory.
+
+ // r = a^-1 in the Montgomery domain. This is
+ // |ec_scalar_to_montgomery| followed by |ec_scalar_inv0_montgomery|, but
+ // |ec_scalar_inv0_montgomery| followed by |ec_scalar_from_montgomery| is
+ // equivalent and slightly more efficient.
+ ec_scalar_inv0_montgomery(group, r, a);
+ ec_scalar_from_montgomery(group, r, r);
+ return 1;
+}
+
+void ec_scalar_inv0_montgomery(const EC_GROUP *group, EC_SCALAR *r,
+ const EC_SCALAR *a) {
+ group->meth->scalar_inv0_montgomery(group, r, a);
+}
+
+int ec_scalar_to_montgomery_inv_vartime(const EC_GROUP *group, EC_SCALAR *r,
+ const EC_SCALAR *a) {
+ return group->meth->scalar_to_montgomery_inv_vartime(group, r, a);
+}
diff --git a/src/crypto/fipsmodule/ec/simple.c b/src/crypto/fipsmodule/ec/simple.c
new file mode 100644
index 0000000..6498bdc
--- /dev/null
+++ b/src/crypto/fipsmodule/ec/simple.c
@@ -0,0 +1,352 @@
+/* Originally written by Bodo Moeller for the OpenSSL project.
+ * ====================================================================
+ * Copyright (c) 1998-2005 The OpenSSL Project. 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.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS 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.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * The elliptic curve binary polynomial software is originally written by
+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems
+ * Laboratories. */
+
+#include <openssl/ec.h>
+
+#include <string.h>
+
+#include <openssl/bn.h>
+#include <openssl/err.h>
+#include <openssl/mem.h>
+
+#include "internal.h"
+#include "../../internal.h"
+
+
+// Most method functions in this file are designed to work with non-trivial
+// representations of field elements if necessary (see ecp_mont.c): while
+// standard modular addition and subtraction are used, the field_mul and
+// field_sqr methods will be used for multiplication, and field_encode and
+// field_decode (if defined) will be used for converting between
+// representations.
+//
+// Functions here specifically assume that if a non-trivial representation is
+// used, it is a Montgomery representation (i.e. 'encoding' means multiplying
+// by some factor R).
+
+int ec_GFp_simple_group_init(EC_GROUP *group) {
+ BN_init(&group->field);
+ group->a_is_minus3 = 0;
+ return 1;
+}
+
+void ec_GFp_simple_group_finish(EC_GROUP *group) {
+ BN_free(&group->field);
+}
+
+int ec_GFp_simple_group_set_curve(EC_GROUP *group, const BIGNUM *p,
+ const BIGNUM *a, const BIGNUM *b,
+ BN_CTX *ctx) {
+ // p must be a prime > 3
+ if (BN_num_bits(p) <= 2 || !BN_is_odd(p)) {
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_FIELD);
+ return 0;
+ }
+
+ int ret = 0;
+ BN_CTX_start(ctx);
+ BIGNUM *tmp = BN_CTX_get(ctx);
+ if (tmp == NULL) {
+ goto err;
+ }
+
+ // group->field
+ if (!BN_copy(&group->field, p)) {
+ goto err;
+ }
+ BN_set_negative(&group->field, 0);
+ // Store the field in minimal form, so it can be used with |BN_ULONG| arrays.
+ bn_set_minimal_width(&group->field);
+
+ if (!ec_bignum_to_felem(group, &group->a, a) ||
+ !ec_bignum_to_felem(group, &group->b, b) ||
+ !ec_bignum_to_felem(group, &group->one, BN_value_one())) {
+ goto err;
+ }
+
+ // group->a_is_minus3
+ if (!BN_copy(tmp, a) ||
+ !BN_add_word(tmp, 3)) {
+ goto err;
+ }
+ group->a_is_minus3 = (0 == BN_cmp(tmp, &group->field));
+
+ ret = 1;
+
+err:
+ BN_CTX_end(ctx);
+ return ret;
+}
+
+int ec_GFp_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
+ BIGNUM *b) {
+ if ((p != NULL && !BN_copy(p, &group->field)) ||
+ (a != NULL && !ec_felem_to_bignum(group, a, &group->a)) ||
+ (b != NULL && !ec_felem_to_bignum(group, b, &group->b))) {
+ return 0;
+ }
+ return 1;
+}
+
+void ec_GFp_simple_point_init(EC_JACOBIAN *point) {
+ OPENSSL_memset(&point->X, 0, sizeof(EC_FELEM));
+ OPENSSL_memset(&point->Y, 0, sizeof(EC_FELEM));
+ OPENSSL_memset(&point->Z, 0, sizeof(EC_FELEM));
+}
+
+void ec_GFp_simple_point_copy(EC_JACOBIAN *dest, const EC_JACOBIAN *src) {
+ OPENSSL_memcpy(&dest->X, &src->X, sizeof(EC_FELEM));
+ OPENSSL_memcpy(&dest->Y, &src->Y, sizeof(EC_FELEM));
+ OPENSSL_memcpy(&dest->Z, &src->Z, sizeof(EC_FELEM));
+}
+
+void ec_GFp_simple_point_set_to_infinity(const EC_GROUP *group,
+ EC_JACOBIAN *point) {
+ // Although it is strictly only necessary to zero Z, we zero the entire point
+ // in case |point| was stack-allocated and yet to be initialized.
+ ec_GFp_simple_point_init(point);
+}
+
+void ec_GFp_simple_invert(const EC_GROUP *group, EC_JACOBIAN *point) {
+ ec_felem_neg(group, &point->Y, &point->Y);
+}
+
+int ec_GFp_simple_is_at_infinity(const EC_GROUP *group,
+ const EC_JACOBIAN *point) {
+ return ec_felem_non_zero_mask(group, &point->Z) == 0;
+}
+
+int ec_GFp_simple_is_on_curve(const EC_GROUP *group,
+ const EC_JACOBIAN *point) {
+ // We have a curve defined by a Weierstrass equation
+ // y^2 = x^3 + a*x + b.
+ // The point to consider is given in Jacobian projective coordinates
+ // where (X, Y, Z) represents (x, y) = (X/Z^2, Y/Z^3).
+ // Substituting this and multiplying by Z^6 transforms the above equation
+ // into
+ // Y^2 = X^3 + a*X*Z^4 + b*Z^6.
+ // To test this, we add up the right-hand side in 'rh'.
+ //
+ // This function may be used when double-checking the secret result of a point
+ // multiplication, so we proceed in constant-time.
+
+ void (*const felem_mul)(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a,
+ const EC_FELEM *b) = group->meth->felem_mul;
+ void (*const felem_sqr)(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a) =
+ group->meth->felem_sqr;
+
+ // rh := X^2
+ EC_FELEM rh;
+ felem_sqr(group, &rh, &point->X);
+
+ EC_FELEM tmp, Z4, Z6;
+ felem_sqr(group, &tmp, &point->Z);
+ felem_sqr(group, &Z4, &tmp);
+ felem_mul(group, &Z6, &Z4, &tmp);
+
+ // rh := rh + a*Z^4
+ if (group->a_is_minus3) {
+ ec_felem_add(group, &tmp, &Z4, &Z4);
+ ec_felem_add(group, &tmp, &tmp, &Z4);
+ ec_felem_sub(group, &rh, &rh, &tmp);
+ } else {
+ felem_mul(group, &tmp, &Z4, &group->a);
+ ec_felem_add(group, &rh, &rh, &tmp);
+ }
+
+ // rh := (rh + a*Z^4)*X
+ felem_mul(group, &rh, &rh, &point->X);
+
+ // rh := rh + b*Z^6
+ felem_mul(group, &tmp, &group->b, &Z6);
+ ec_felem_add(group, &rh, &rh, &tmp);
+
+ // 'lh' := Y^2
+ felem_sqr(group, &tmp, &point->Y);
+
+ ec_felem_sub(group, &tmp, &tmp, &rh);
+ BN_ULONG not_equal = ec_felem_non_zero_mask(group, &tmp);
+
+ // If Z = 0, the point is infinity, which is always on the curve.
+ BN_ULONG not_infinity = ec_felem_non_zero_mask(group, &point->Z);
+
+ return 1 & ~(not_infinity & not_equal);
+}
+
+int ec_GFp_simple_points_equal(const EC_GROUP *group, const EC_JACOBIAN *a,
+ const EC_JACOBIAN *b) {
+ // This function is implemented in constant-time for two reasons. First,
+ // although EC points are usually public, their Jacobian Z coordinates may be
+ // secret, or at least are not obviously public. Second, more complex
+ // protocols will sometimes manipulate secret points.
+ //
+ // This does mean that we pay a 6M+2S Jacobian comparison when comparing two
+ // publicly affine points costs no field operations at all. If needed, we can
+ // restore this optimization by keeping better track of affine vs. Jacobian
+ // forms. See https://crbug.com/boringssl/326.
+
+ // If neither |a| or |b| is infinity, we have to decide whether
+ // (X_a/Z_a^2, Y_a/Z_a^3) = (X_b/Z_b^2, Y_b/Z_b^3),
+ // or equivalently, whether
+ // (X_a*Z_b^2, Y_a*Z_b^3) = (X_b*Z_a^2, Y_b*Z_a^3).
+
+ void (*const felem_mul)(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a,
+ const EC_FELEM *b) = group->meth->felem_mul;
+ void (*const felem_sqr)(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a) =
+ group->meth->felem_sqr;
+
+ EC_FELEM tmp1, tmp2, Za23, Zb23;
+ felem_sqr(group, &Zb23, &b->Z); // Zb23 = Z_b^2
+ felem_mul(group, &tmp1, &a->X, &Zb23); // tmp1 = X_a * Z_b^2
+ felem_sqr(group, &Za23, &a->Z); // Za23 = Z_a^2
+ felem_mul(group, &tmp2, &b->X, &Za23); // tmp2 = X_b * Z_a^2
+ ec_felem_sub(group, &tmp1, &tmp1, &tmp2);
+ const BN_ULONG x_not_equal = ec_felem_non_zero_mask(group, &tmp1);
+
+ felem_mul(group, &Zb23, &Zb23, &b->Z); // Zb23 = Z_b^3
+ felem_mul(group, &tmp1, &a->Y, &Zb23); // tmp1 = Y_a * Z_b^3
+ felem_mul(group, &Za23, &Za23, &a->Z); // Za23 = Z_a^3
+ felem_mul(group, &tmp2, &b->Y, &Za23); // tmp2 = Y_b * Z_a^3
+ ec_felem_sub(group, &tmp1, &tmp1, &tmp2);
+ const BN_ULONG y_not_equal = ec_felem_non_zero_mask(group, &tmp1);
+ const BN_ULONG x_and_y_equal = ~(x_not_equal | y_not_equal);
+
+ const BN_ULONG a_not_infinity = ec_felem_non_zero_mask(group, &a->Z);
+ const BN_ULONG b_not_infinity = ec_felem_non_zero_mask(group, &b->Z);
+ const BN_ULONG a_and_b_infinity = ~(a_not_infinity | b_not_infinity);
+
+ const BN_ULONG equal =
+ a_and_b_infinity | (a_not_infinity & b_not_infinity & x_and_y_equal);
+ return equal & 1;
+}
+
+int ec_affine_jacobian_equal(const EC_GROUP *group, const EC_AFFINE *a,
+ const EC_JACOBIAN *b) {
+ // If |b| is not infinity, we have to decide whether
+ // (X_a, Y_a) = (X_b/Z_b^2, Y_b/Z_b^3),
+ // or equivalently, whether
+ // (X_a*Z_b^2, Y_a*Z_b^3) = (X_b, Y_b).
+
+ void (*const felem_mul)(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a,
+ const EC_FELEM *b) = group->meth->felem_mul;
+ void (*const felem_sqr)(const EC_GROUP *, EC_FELEM *r, const EC_FELEM *a) =
+ group->meth->felem_sqr;
+
+ EC_FELEM tmp, Zb2;
+ felem_sqr(group, &Zb2, &b->Z); // Zb2 = Z_b^2
+ felem_mul(group, &tmp, &a->X, &Zb2); // tmp = X_a * Z_b^2
+ ec_felem_sub(group, &tmp, &tmp, &b->X);
+ const BN_ULONG x_not_equal = ec_felem_non_zero_mask(group, &tmp);
+
+ felem_mul(group, &tmp, &a->Y, &Zb2); // tmp = Y_a * Z_b^2
+ felem_mul(group, &tmp, &tmp, &b->Z); // tmp = Y_a * Z_b^3
+ ec_felem_sub(group, &tmp, &tmp, &b->Y);
+ const BN_ULONG y_not_equal = ec_felem_non_zero_mask(group, &tmp);
+ const BN_ULONG x_and_y_equal = ~(x_not_equal | y_not_equal);
+
+ const BN_ULONG b_not_infinity = ec_felem_non_zero_mask(group, &b->Z);
+
+ const BN_ULONG equal = b_not_infinity & x_and_y_equal;
+ return equal & 1;
+}
+
+int ec_GFp_simple_cmp_x_coordinate(const EC_GROUP *group, const EC_JACOBIAN *p,
+ const EC_SCALAR *r) {
+ if (ec_GFp_simple_is_at_infinity(group, p)) {
+ // |ec_get_x_coordinate_as_scalar| will check this internally, but this way
+ // we do not push to the error queue.
+ return 0;
+ }
+
+ EC_SCALAR x;
+ return ec_get_x_coordinate_as_scalar(group, &x, p) &&
+ ec_scalar_equal_vartime(group, &x, r);
+}
+
+void ec_GFp_simple_felem_to_bytes(const EC_GROUP *group, uint8_t *out,
+ size_t *out_len, const EC_FELEM *in) {
+ size_t len = BN_num_bytes(&group->field);
+ bn_words_to_big_endian(out, len, in->words, group->field.width);
+ *out_len = len;
+}
+
+int ec_GFp_simple_felem_from_bytes(const EC_GROUP *group, EC_FELEM *out,
+ const uint8_t *in, size_t len) {
+ if (len != BN_num_bytes(&group->field)) {
+ OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
+ return 0;
+ }
+
+ bn_big_endian_to_words(out->words, group->field.width, in, len);
+
+ if (!bn_less_than_words(out->words, group->field.d, group->field.width)) {
+ OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
+ return 0;
+ }
+
+ return 1;
+}
diff --git a/src/crypto/fipsmodule/ec/simple_mul.c b/src/crypto/fipsmodule/ec/simple_mul.c
new file mode 100644
index 0000000..9a72a66
--- /dev/null
+++ b/src/crypto/fipsmodule/ec/simple_mul.c
@@ -0,0 +1,269 @@
+/* Copyright (c) 2018, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <openssl/ec.h>
+
+#include <assert.h>
+
+#include "internal.h"
+#include "../bn/internal.h"
+#include "../../internal.h"
+
+
+void ec_GFp_mont_mul(const EC_GROUP *group, EC_JACOBIAN *r,
+ const EC_JACOBIAN *p, const EC_SCALAR *scalar) {
+ // This is a generic implementation for uncommon curves that not do not
+ // warrant a tuned one. It uses unsigned digits so that the doubling case in
+ // |ec_GFp_mont_add| is always unreachable, erring on safety and simplicity.
+
+ // Compute a table of the first 32 multiples of |p| (including infinity).
+ EC_JACOBIAN precomp[32];
+ ec_GFp_simple_point_set_to_infinity(group, &precomp[0]);
+ ec_GFp_simple_point_copy(&precomp[1], p);
+ for (size_t j = 2; j < OPENSSL_ARRAY_SIZE(precomp); j++) {
+ if (j & 1) {
+ ec_GFp_mont_add(group, &precomp[j], &precomp[1], &precomp[j - 1]);
+ } else {
+ ec_GFp_mont_dbl(group, &precomp[j], &precomp[j / 2]);
+ }
+ }
+
+ // Divide bits in |scalar| into windows.
+ unsigned bits = BN_num_bits(&group->order);
+ int r_is_at_infinity = 1;
+ for (unsigned i = bits - 1; i < bits; i--) {
+ if (!r_is_at_infinity) {
+ ec_GFp_mont_dbl(group, r, r);
+ }
+ if (i % 5 == 0) {
+ // Compute the next window value.
+ const size_t width = group->order.width;
+ uint8_t window = bn_is_bit_set_words(scalar->words, width, i + 4) << 4;
+ window |= bn_is_bit_set_words(scalar->words, width, i + 3) << 3;
+ window |= bn_is_bit_set_words(scalar->words, width, i + 2) << 2;
+ window |= bn_is_bit_set_words(scalar->words, width, i + 1) << 1;
+ window |= bn_is_bit_set_words(scalar->words, width, i);
+
+ // Select the entry in constant-time.
+ EC_JACOBIAN tmp;
+ OPENSSL_memset(&tmp, 0, sizeof(EC_JACOBIAN));
+ for (size_t j = 0; j < OPENSSL_ARRAY_SIZE(precomp); j++) {
+ BN_ULONG mask = constant_time_eq_w(j, window);
+ ec_point_select(group, &tmp, mask, &precomp[j], &tmp);
+ }
+
+ if (r_is_at_infinity) {
+ ec_GFp_simple_point_copy(r, &tmp);
+ r_is_at_infinity = 0;
+ } else {
+ ec_GFp_mont_add(group, r, r, &tmp);
+ }
+ }
+ }
+ if (r_is_at_infinity) {
+ ec_GFp_simple_point_set_to_infinity(group, r);
+ }
+}
+
+void ec_GFp_mont_mul_base(const EC_GROUP *group, EC_JACOBIAN *r,
+ const EC_SCALAR *scalar) {
+ ec_GFp_mont_mul(group, r, &group->generator->raw, scalar);
+}
+
+static void ec_GFp_mont_batch_precomp(const EC_GROUP *group, EC_JACOBIAN *out,
+ size_t num, const EC_JACOBIAN *p) {
+ assert(num > 1);
+ ec_GFp_simple_point_set_to_infinity(group, &out[0]);
+ ec_GFp_simple_point_copy(&out[1], p);
+ for (size_t j = 2; j < num; j++) {
+ if (j & 1) {
+ ec_GFp_mont_add(group, &out[j], &out[1], &out[j - 1]);
+ } else {
+ ec_GFp_mont_dbl(group, &out[j], &out[j / 2]);
+ }
+ }
+}
+
+static void ec_GFp_mont_batch_get_window(const EC_GROUP *group,
+ EC_JACOBIAN *out,
+ const EC_JACOBIAN precomp[17],
+ const EC_SCALAR *scalar, unsigned i) {
+ const size_t width = group->order.width;
+ uint8_t window = bn_is_bit_set_words(scalar->words, width, i + 4) << 5;
+ window |= bn_is_bit_set_words(scalar->words, width, i + 3) << 4;
+ window |= bn_is_bit_set_words(scalar->words, width, i + 2) << 3;
+ window |= bn_is_bit_set_words(scalar->words, width, i + 1) << 2;
+ window |= bn_is_bit_set_words(scalar->words, width, i) << 1;
+ if (i > 0) {
+ window |= bn_is_bit_set_words(scalar->words, width, i - 1);
+ }
+ crypto_word_t sign, digit;
+ ec_GFp_nistp_recode_scalar_bits(&sign, &digit, window);
+
+ // Select the entry in constant-time.
+ OPENSSL_memset(out, 0, sizeof(EC_JACOBIAN));
+ for (size_t j = 0; j < 17; j++) {
+ BN_ULONG mask = constant_time_eq_w(j, digit);
+ ec_point_select(group, out, mask, &precomp[j], out);
+ }
+
+ // Negate if necessary.
+ EC_FELEM neg_Y;
+ ec_felem_neg(group, &neg_Y, &out->Y);
+ crypto_word_t sign_mask = sign;
+ sign_mask = 0u - sign_mask;
+ ec_felem_select(group, &out->Y, sign_mask, &neg_Y, &out->Y);
+}
+
+void ec_GFp_mont_mul_batch(const EC_GROUP *group, EC_JACOBIAN *r,
+ const EC_JACOBIAN *p0, const EC_SCALAR *scalar0,
+ const EC_JACOBIAN *p1, const EC_SCALAR *scalar1,
+ const EC_JACOBIAN *p2, const EC_SCALAR *scalar2) {
+ EC_JACOBIAN precomp[3][17];
+ ec_GFp_mont_batch_precomp(group, precomp[0], 17, p0);
+ ec_GFp_mont_batch_precomp(group, precomp[1], 17, p1);
+ if (p2 != NULL) {
+ ec_GFp_mont_batch_precomp(group, precomp[2], 17, p2);
+ }
+
+ // Divide bits in |scalar| into windows.
+ unsigned bits = BN_num_bits(&group->order);
+ int r_is_at_infinity = 1;
+ for (unsigned i = bits; i <= bits; i--) {
+ if (!r_is_at_infinity) {
+ ec_GFp_mont_dbl(group, r, r);
+ }
+ if (i % 5 == 0) {
+ EC_JACOBIAN tmp;
+ ec_GFp_mont_batch_get_window(group, &tmp, precomp[0], scalar0, i);
+ if (r_is_at_infinity) {
+ ec_GFp_simple_point_copy(r, &tmp);
+ r_is_at_infinity = 0;
+ } else {
+ ec_GFp_mont_add(group, r, r, &tmp);
+ }
+
+ ec_GFp_mont_batch_get_window(group, &tmp, precomp[1], scalar1, i);
+ ec_GFp_mont_add(group, r, r, &tmp);
+
+ if (p2 != NULL) {
+ ec_GFp_mont_batch_get_window(group, &tmp, precomp[2], scalar2, i);
+ ec_GFp_mont_add(group, r, r, &tmp);
+ }
+ }
+ }
+ if (r_is_at_infinity) {
+ ec_GFp_simple_point_set_to_infinity(group, r);
+ }
+}
+
+static unsigned ec_GFp_mont_comb_stride(const EC_GROUP *group) {
+ return (BN_num_bits(&group->field) + EC_MONT_PRECOMP_COMB_SIZE - 1) /
+ EC_MONT_PRECOMP_COMB_SIZE;
+}
+
+int ec_GFp_mont_init_precomp(const EC_GROUP *group, EC_PRECOMP *out,
+ const EC_JACOBIAN *p) {
+ // comb[i - 1] stores the ith element of the comb. That is, if i is
+ // b4 * 2^4 + b3 * 2^3 + ... + b0 * 2^0, it stores k * |p|, where k is
+ // b4 * 2^(4*stride) + b3 * 2^(3*stride) + ... + b0 * 2^(0*stride). stride
+ // here is |ec_GFp_mont_comb_stride|. We store at index i - 1 because the 0th
+ // comb entry is always infinity.
+ EC_JACOBIAN comb[(1 << EC_MONT_PRECOMP_COMB_SIZE) - 1];
+ unsigned stride = ec_GFp_mont_comb_stride(group);
+
+ // We compute the comb sequentially by the highest set bit. Initially, all
+ // entries up to 2^0 are filled.
+ comb[(1 << 0) - 1] = *p;
+ for (unsigned i = 1; i < EC_MONT_PRECOMP_COMB_SIZE; i++) {
+ // Compute entry 2^i by doubling the entry for 2^(i-1) |stride| times.
+ unsigned bit = 1 << i;
+ ec_GFp_mont_dbl(group, &comb[bit - 1], &comb[bit / 2 - 1]);
+ for (unsigned j = 1; j < stride; j++) {
+ ec_GFp_mont_dbl(group, &comb[bit - 1], &comb[bit - 1]);
+ }
+ // Compute entries from 2^i + 1 to 2^i + (2^i - 1) by adding entry 2^i to
+ // a previous entry.
+ for (unsigned j = 1; j < bit; j++) {
+ ec_GFp_mont_add(group, &comb[bit + j - 1], &comb[bit - 1], &comb[j - 1]);
+ }
+ }
+
+ // Store the comb in affine coordinates to shrink the table. (This reduces
+ // cache pressure and makes the constant-time selects faster.)
+ static_assert(OPENSSL_ARRAY_SIZE(comb) == OPENSSL_ARRAY_SIZE(out->comb),
+ "comb sizes did not match");
+ return ec_jacobian_to_affine_batch(group, out->comb, comb,
+ OPENSSL_ARRAY_SIZE(comb));
+}
+
+static void ec_GFp_mont_get_comb_window(const EC_GROUP *group,
+ EC_JACOBIAN *out,
+ const EC_PRECOMP *precomp,
+ const EC_SCALAR *scalar, unsigned i) {
+ const size_t width = group->order.width;
+ unsigned stride = ec_GFp_mont_comb_stride(group);
+ // Select the bits corresponding to the comb shifted up by |i|.
+ unsigned window = 0;
+ for (unsigned j = 0; j < EC_MONT_PRECOMP_COMB_SIZE; j++) {
+ window |= bn_is_bit_set_words(scalar->words, width, j * stride + i)
+ << j;
+ }
+
+ // Select precomp->comb[window - 1]. If |window| is zero, |match| will always
+ // be zero, which will leave |out| at infinity.
+ OPENSSL_memset(out, 0, sizeof(EC_JACOBIAN));
+ for (unsigned j = 0; j < OPENSSL_ARRAY_SIZE(precomp->comb); j++) {
+ BN_ULONG match = constant_time_eq_w(window, j + 1);
+ ec_felem_select(group, &out->X, match, &precomp->comb[j].X, &out->X);
+ ec_felem_select(group, &out->Y, match, &precomp->comb[j].Y, &out->Y);
+ }
+ BN_ULONG is_infinity = constant_time_is_zero_w(window);
+ ec_felem_select(group, &out->Z, is_infinity, &out->Z, &group->one);
+}
+
+void ec_GFp_mont_mul_precomp(const EC_GROUP *group, EC_JACOBIAN *r,
+ const EC_PRECOMP *p0, const EC_SCALAR *scalar0,
+ const EC_PRECOMP *p1, const EC_SCALAR *scalar1,
+ const EC_PRECOMP *p2, const EC_SCALAR *scalar2) {
+ unsigned stride = ec_GFp_mont_comb_stride(group);
+ int r_is_at_infinity = 1;
+ for (unsigned i = stride - 1; i < stride; i--) {
+ if (!r_is_at_infinity) {
+ ec_GFp_mont_dbl(group, r, r);
+ }
+
+ EC_JACOBIAN tmp;
+ ec_GFp_mont_get_comb_window(group, &tmp, p0, scalar0, i);
+ if (r_is_at_infinity) {
+ ec_GFp_simple_point_copy(r, &tmp);
+ r_is_at_infinity = 0;
+ } else {
+ ec_GFp_mont_add(group, r, r, &tmp);
+ }
+
+ if (p1 != NULL) {
+ ec_GFp_mont_get_comb_window(group, &tmp, p1, scalar1, i);
+ ec_GFp_mont_add(group, r, r, &tmp);
+ }
+
+ if (p2 != NULL) {
+ ec_GFp_mont_get_comb_window(group, &tmp, p2, scalar2, i);
+ ec_GFp_mont_add(group, r, r, &tmp);
+ }
+ }
+ if (r_is_at_infinity) {
+ ec_GFp_simple_point_set_to_infinity(group, r);
+ }
+}
diff --git a/src/crypto/fipsmodule/ec/util.c b/src/crypto/fipsmodule/ec/util.c
new file mode 100644
index 0000000..c4323f2
--- /dev/null
+++ b/src/crypto/fipsmodule/ec/util.c
@@ -0,0 +1,255 @@
+/* Copyright (c) 2015, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <openssl/base.h>
+
+#include <openssl/ec.h>
+
+#include "internal.h"
+
+
+// This function looks at 5+1 scalar bits (5 current, 1 adjacent less
+// significant bit), and recodes them into a signed digit for use in fast point
+// multiplication: the use of signed rather than unsigned digits means that
+// fewer points need to be precomputed, given that point inversion is easy (a
+// precomputed point dP makes -dP available as well).
+//
+// BACKGROUND:
+//
+// Signed digits for multiplication were introduced by Booth ("A signed binary
+// multiplication technique", Quart. Journ. Mech. and Applied Math., vol. IV,
+// pt. 2 (1951), pp. 236-240), in that case for multiplication of integers.
+// Booth's original encoding did not generally improve the density of nonzero
+// digits over the binary representation, and was merely meant to simplify the
+// handling of signed factors given in two's complement; but it has since been
+// shown to be the basis of various signed-digit representations that do have
+// further advantages, including the wNAF, using the following general
+// approach:
+//
+// (1) Given a binary representation
+//
+// b_k ... b_2 b_1 b_0,
+//
+// of a nonnegative integer (b_k in {0, 1}), rewrite it in digits 0, 1, -1
+// by using bit-wise subtraction as follows:
+//
+// b_k b_(k-1) ... b_2 b_1 b_0
+// - b_k ... b_3 b_2 b_1 b_0
+// -----------------------------------------
+// s_(k+1) s_k ... s_3 s_2 s_1 s_0
+//
+// A left-shift followed by subtraction of the original value yields a new
+// representation of the same value, using signed bits s_i = b_(i-1) - b_i.
+// This representation from Booth's paper has since appeared in the
+// literature under a variety of different names including "reversed binary
+// form", "alternating greedy expansion", "mutual opposite form", and
+// "sign-alternating {+-1}-representation".
+//
+// An interesting property is that among the nonzero bits, values 1 and -1
+// strictly alternate.
+//
+// (2) Various window schemes can be applied to the Booth representation of
+// integers: for example, right-to-left sliding windows yield the wNAF
+// (a signed-digit encoding independently discovered by various researchers
+// in the 1990s), and left-to-right sliding windows yield a left-to-right
+// equivalent of the wNAF (independently discovered by various researchers
+// around 2004).
+//
+// To prevent leaking information through side channels in point multiplication,
+// we need to recode the given integer into a regular pattern: sliding windows
+// as in wNAFs won't do, we need their fixed-window equivalent -- which is a few
+// decades older: we'll be using the so-called "modified Booth encoding" due to
+// MacSorley ("High-speed arithmetic in binary computers", Proc. IRE, vol. 49
+// (1961), pp. 67-91), in a radix-2^5 setting. That is, we always combine five
+// signed bits into a signed digit:
+//
+// s_(5j + 4) s_(5j + 3) s_(5j + 2) s_(5j + 1) s_(5j)
+//
+// The sign-alternating property implies that the resulting digit values are
+// integers from -16 to 16.
+//
+// Of course, we don't actually need to compute the signed digits s_i as an
+// intermediate step (that's just a nice way to see how this scheme relates
+// to the wNAF): a direct computation obtains the recoded digit from the
+// six bits b_(5j + 4) ... b_(5j - 1).
+//
+// This function takes those six bits as an integer (0 .. 63), writing the
+// recoded digit to *sign (0 for positive, 1 for negative) and *digit (absolute
+// value, in the range 0 .. 16). Note that this integer essentially provides
+// the input bits "shifted to the left" by one position: for example, the input
+// to compute the least significant recoded digit, given that there's no bit
+// b_-1, has to be b_4 b_3 b_2 b_1 b_0 0.
+//
+// DOUBLING CASE:
+//
+// Point addition formulas for short Weierstrass curves are often incomplete.
+// Edge cases such as P + P or P + ∞ must be handled separately. This
+// complicates constant-time requirements. P + ∞ cannot be avoided (any window
+// may be zero) and is handled with constant-time selects. P + P (where P is not
+// ∞) usually is not. Instead, windowing strategies are chosen to avoid this
+// case. Whether this happens depends on the group order.
+//
+// Let w be the window width (in this function, w = 5). The non-trivial doubling
+// case in single-point scalar multiplication may occur if and only if the
+// 2^(w-1) bit of the group order is zero.
+//
+// Note the above only holds if the scalar is fully reduced and the group order
+// is a prime that is much larger than 2^w. It also only holds when windows
+// are applied from most significant to least significant, doubling between each
+// window. It does not apply to more complex table strategies such as
+// |EC_GFp_nistz256_method|.
+//
+// PROOF:
+//
+// Let n be the group order. Let l be the number of bits needed to represent n.
+// Assume there exists some 0 <= k < n such that signed w-bit windowed
+// multiplication hits the doubling case.
+//
+// Windowed multiplication consists of iterating over groups of s_i (defined
+// above based on k's binary representation) from most to least significant. At
+// iteration i (for i = ..., 3w, 2w, w, 0, starting from the most significant
+// window), we:
+//
+// 1. Double the accumulator A, w times. Let A_i be the value of A at this
+// point.
+//
+// 2. Set A to T_i + A_i, where T_i is a precomputed multiple of P
+// corresponding to the window s_(i+w-1) ... s_i.
+//
+// Let j be the index such that A_j = T_j ≠ ∞. Looking at A_i and T_i as
+// multiples of P, define a_i and t_i to be scalar coefficients of A_i and T_i.
+// Thus a_j = t_j ≠ 0 (mod n). Note a_i and t_i may not be reduced mod n. t_i is
+// the value of the w signed bits s_(i+w-1) ... s_i. a_i is computed as a_i =
+// 2^w * (a_(i+w) + t_(i+w)).
+//
+// t_i is bounded by -2^(w-1) <= t_i <= 2^(w-1). Additionally, we may write it
+// in terms of unsigned bits b_i. t_i consists of signed bits s_(i+w-1) ... s_i.
+// This is computed as:
+//
+// b_(i+w-2) b_(i+w-3) ... b_i b_(i-1)
+// - b_(i+w-1) b_(i+w-2) ... b_(i+1) b_i
+// --------------------------------------------
+// t_i = s_(i+w-1) s_(i+w-2) ... s_(i+1) s_i
+//
+// Observe that b_(i+w-2) through b_i occur in both terms. Let x be the integer
+// represented by that bit string, i.e. 2^(w-2)*b_(i+w-2) + ... + b_i.
+//
+// t_i = (2*x + b_(i-1)) - (2^(w-1)*b_(i+w-1) + x)
+// = x - 2^(w-1)*b_(i+w-1) + b_(i-1)
+//
+// Or, using C notation for bit operations:
+//
+// t_i = (k>>i) & ((1<<(w-1)) - 1) - (k>>i) & (1<<(w-1)) + (k>>(i-1)) & 1
+//
+// Note b_(i-1) is added in left-shifted by one (or doubled) from its place.
+// This is compensated by t_(i-w)'s subtraction term. Thus, a_i may be computed
+// by adding b_l b_(l-1) ... b_(i+1) b_i and an extra copy of b_(i-1). In C
+// notation, this is:
+//
+// a_i = (k>>(i+w)) << w + ((k>>(i+w-1)) & 1) << w
+//
+// Observe that, while t_i may be positive or negative, a_i is bounded by
+// 0 <= a_i < n + 2^w. Additionally, a_i can only be zero if b_(i+w-1) and up
+// are all zero. (Note this implies a non-trivial P + (-P) is unreachable for
+// all groups. That would imply the subsequent a_i is zero, which means all
+// terms thus far were zero.)
+//
+// Returning to our doubling position, we have a_j = t_j (mod n). We now
+// determine the value of a_j - t_j, which must be divisible by n. Our bounds on
+// a_j and t_j imply a_j - t_j is 0 or n. If it is 0, a_j = t_j. However, 2^w
+// divides a_j and -2^(w-1) <= t_j <= 2^(w-1), so this can only happen if
+// a_j = t_j = 0, which is a trivial doubling. Therefore, a_j - t_j = n.
+//
+// Now we determine j. Suppose j > 0. w divides j, so j >= w. Then,
+//
+// n = a_j - t_j = (k>>(j+w)) << w + ((k>>(j+w-1)) & 1) << w - t_j
+// <= k/2^j + 2^w - t_j
+// < n/2^w + 2^w + 2^(w-1)
+//
+// n is much larger than 2^w, so this is impossible. Thus, j = 0: only the final
+// addition may hit the doubling case.
+//
+// Finally, we consider bit patterns for n and k. Divide k into k_H + k_M + k_L
+// such that k_H is the contribution from b_(l-1) .. b_w, k_M is the
+// contribution from b_(w-1), and k_L is the contribution from b_(w-2) ... b_0.
+// That is:
+//
+// - 2^w divides k_H
+// - k_M is 0 or 2^(w-1)
+// - 0 <= k_L < 2^(w-1)
+//
+// Divide n into n_H + n_M + n_L similarly. We thus have:
+//
+// t_0 = (k>>0) & ((1<<(w-1)) - 1) - (k>>0) & (1<<(w-1)) + (k>>(0-1)) & 1
+// = k & ((1<<(w-1)) - 1) - k & (1<<(w-1))
+// = k_L - k_M
+//
+// a_0 = (k>>(0+w)) << w + ((k>>(0+w-1)) & 1) << w
+// = (k>>w) << w + ((k>>(w-1)) & 1) << w
+// = k_H + 2*k_M
+//
+// n = a_0 - t_0
+// n_H + n_M + n_L = (k_H + 2*k_M) - (k_L - k_M)
+// = k_H + 3*k_M - k_L
+//
+// k_H - k_L < k and k < n, so k_H - k_L ≠ n. Therefore k_M is not 0 and must be
+// 2^(w-1). Now we consider k_H and n_H. We know k_H <= n_H. Suppose k_H = n_H.
+// Then,
+//
+// n_M + n_L = 3*(2^(w-1)) - k_L
+// > 3*(2^(w-1)) - 2^(w-1)
+// = 2^w
+//
+// Contradiction (n_M + n_L is the bottom w bits of n). Thus k_H < n_H. Suppose
+// k_H < n_H - 2*2^w. Then,
+//
+// n_H + n_M + n_L = k_H + 3*(2^(w-1)) - k_L
+// < n_H - 2*2^w + 3*(2^(w-1)) - k_L
+// n_M + n_L < -2^(w-1) - k_L
+//
+// Contradiction. Thus, k_H = n_H - 2^w. (Note 2^w divides n_H and k_H.) Thus,
+//
+// n_H + n_M + n_L = k_H + 3*(2^(w-1)) - k_L
+// = n_H - 2^w + 3*(2^(w-1)) - k_L
+// n_M + n_L = 2^(w-1) - k_L
+// <= 2^(w-1)
+//
+// Equality would mean 2^(w-1) divides n, which is impossible if n is prime.
+// Thus n_M + n_L < 2^(w-1), so n_M is zero, proving our condition.
+//
+// This proof constructs k, so, to show the converse, let k_H = n_H - 2^w,
+// k_M = 2^(w-1), k_L = 2^(w-1) - n_L. This will result in a non-trivial point
+// doubling in the final addition and is the only such scalar.
+//
+// COMMON CURVES:
+//
+// The group orders for common curves end in the following bit patterns:
+//
+// P-521: ...00001001; w = 4 is okay
+// P-384: ...01110011; w = 2, 5, 6, 7 are okay
+// P-256: ...01010001; w = 5, 7 are okay
+// P-224: ...00111101; w = 3, 4, 5, 6 are okay
+void ec_GFp_nistp_recode_scalar_bits(crypto_word_t *sign, crypto_word_t *digit,
+ crypto_word_t in) {
+ crypto_word_t s, d;
+
+ s = ~((in >> 5) - 1); /* sets all bits to MSB(in), 'in' seen as
+ * 6-bit value */
+ d = (1 << 6) - in - 1;
+ d = (d & s) | (in & ~s);
+ d = (d >> 1) + (d & 1);
+
+ *sign = s & 1;
+ *digit = d;
+}
diff --git a/src/crypto/fipsmodule/ec/wnaf.c b/src/crypto/fipsmodule/ec/wnaf.c
new file mode 100644
index 0000000..beb9295
--- /dev/null
+++ b/src/crypto/fipsmodule/ec/wnaf.c
@@ -0,0 +1,269 @@
+/* Originally written by Bodo Moeller for the OpenSSL project.
+ * ====================================================================
+ * Copyright (c) 1998-2005 The OpenSSL Project. 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.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED 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 THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS 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.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * The elliptic curve binary polynomial software is originally written by
+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems
+ * Laboratories. */
+
+#include <openssl/ec.h>
+
+#include <assert.h>
+#include <string.h>
+
+#include <openssl/bn.h>
+#include <openssl/err.h>
+#include <openssl/mem.h>
+#include <openssl/thread.h>
+
+#include "internal.h"
+#include "../bn/internal.h"
+#include "../../internal.h"
+
+
+// This file implements the wNAF-based interleaving multi-exponentiation method
+// at:
+// http://link.springer.com/chapter/10.1007%2F3-540-45537-X_13
+// http://www.bmoeller.de/pdf/TI-01-08.multiexp.pdf
+
+void ec_compute_wNAF(const EC_GROUP *group, int8_t *out,
+ const EC_SCALAR *scalar, size_t bits, int w) {
+ // 'int8_t' can represent integers with absolute values less than 2^7.
+ assert(0 < w && w <= 7);
+ assert(bits != 0);
+ int bit = 1 << w; // 2^w, at most 128
+ int next_bit = bit << 1; // 2^(w+1), at most 256
+ int mask = next_bit - 1; // at most 255
+
+ int window_val = scalar->words[0] & mask;
+ for (size_t j = 0; j < bits + 1; j++) {
+ assert(0 <= window_val && window_val <= next_bit);
+ int digit = 0;
+ if (window_val & 1) {
+ assert(0 < window_val && window_val < next_bit);
+ if (window_val & bit) {
+ digit = window_val - next_bit;
+ // We know -next_bit < digit < 0 and window_val - digit = next_bit.
+
+ // modified wNAF
+ if (j + w + 1 >= bits) {
+ // special case for generating modified wNAFs:
+ // no new bits will be added into window_val,
+ // so using a positive digit here will decrease
+ // the total length of the representation
+
+ digit = window_val & (mask >> 1);
+ // We know 0 < digit < bit and window_val - digit = bit.
+ }
+ } else {
+ digit = window_val;
+ // We know 0 < digit < bit and window_val - digit = 0.
+ }
+
+ window_val -= digit;
+
+ // Now window_val is 0 or 2^(w+1) in standard wNAF generation.
+ // For modified window NAFs, it may also be 2^w.
+ //
+ // See the comments above for the derivation of each of these bounds.
+ assert(window_val == 0 || window_val == next_bit || window_val == bit);
+ assert(-bit < digit && digit < bit);
+
+ // window_val was odd, so digit is also odd.
+ assert(digit & 1);
+ }
+
+ out[j] = digit;
+
+ // Incorporate the next bit. Previously, |window_val| <= |next_bit|, so if
+ // we shift and add at most one copy of |bit|, this will continue to hold
+ // afterwards.
+ window_val >>= 1;
+ window_val +=
+ bit * bn_is_bit_set_words(scalar->words, group->order.width, j + w + 1);
+ assert(window_val <= next_bit);
+ }
+
+ // bits + 1 entries should be sufficient to consume all bits.
+ assert(window_val == 0);
+}
+
+// compute_precomp sets |out[i]| to (2*i+1)*p, for i from 0 to |len|.
+static void compute_precomp(const EC_GROUP *group, EC_JACOBIAN *out,
+ const EC_JACOBIAN *p, size_t len) {
+ ec_GFp_simple_point_copy(&out[0], p);
+ EC_JACOBIAN two_p;
+ ec_GFp_mont_dbl(group, &two_p, p);
+ for (size_t i = 1; i < len; i++) {
+ ec_GFp_mont_add(group, &out[i], &out[i - 1], &two_p);
+ }
+}
+
+static void lookup_precomp(const EC_GROUP *group, EC_JACOBIAN *out,
+ const EC_JACOBIAN *precomp, int digit) {
+ if (digit < 0) {
+ digit = -digit;
+ ec_GFp_simple_point_copy(out, &precomp[digit >> 1]);
+ ec_GFp_simple_invert(group, out);
+ } else {
+ ec_GFp_simple_point_copy(out, &precomp[digit >> 1]);
+ }
+}
+
+// EC_WNAF_WINDOW_BITS is the window size to use for |ec_GFp_mont_mul_public|.
+#define EC_WNAF_WINDOW_BITS 4
+
+// EC_WNAF_TABLE_SIZE is the table size to use for |ec_GFp_mont_mul_public|.
+#define EC_WNAF_TABLE_SIZE (1 << (EC_WNAF_WINDOW_BITS - 1))
+
+// EC_WNAF_STACK is the number of points worth of data to stack-allocate and
+// avoid a malloc.
+#define EC_WNAF_STACK 3
+
+int ec_GFp_mont_mul_public_batch(const EC_GROUP *group, EC_JACOBIAN *r,
+ const EC_SCALAR *g_scalar,
+ const EC_JACOBIAN *points,
+ const EC_SCALAR *scalars, size_t num) {
+ size_t bits = BN_num_bits(&group->order);
+ size_t wNAF_len = bits + 1;
+
+ int ret = 0;
+ int8_t wNAF_stack[EC_WNAF_STACK][EC_MAX_BYTES * 8 + 1];
+ int8_t (*wNAF_alloc)[EC_MAX_BYTES * 8 + 1] = NULL;
+ int8_t (*wNAF)[EC_MAX_BYTES * 8 + 1];
+ EC_JACOBIAN precomp_stack[EC_WNAF_STACK][EC_WNAF_TABLE_SIZE];
+ EC_JACOBIAN (*precomp_alloc)[EC_WNAF_TABLE_SIZE] = NULL;
+ EC_JACOBIAN (*precomp)[EC_WNAF_TABLE_SIZE];
+ if (num <= EC_WNAF_STACK) {
+ wNAF = wNAF_stack;
+ precomp = precomp_stack;
+ } else {
+ if (num >= ((size_t)-1) / sizeof(wNAF_alloc[0]) ||
+ num >= ((size_t)-1) / sizeof(precomp_alloc[0])) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_OVERFLOW);
+ goto err;
+ }
+ wNAF_alloc = OPENSSL_malloc(num * sizeof(wNAF_alloc[0]));
+ precomp_alloc = OPENSSL_malloc(num * sizeof(precomp_alloc[0]));
+ if (wNAF_alloc == NULL || precomp_alloc == NULL) {
+ goto err;
+ }
+ wNAF = wNAF_alloc;
+ precomp = precomp_alloc;
+ }
+
+ int8_t g_wNAF[EC_MAX_BYTES * 8 + 1];
+ EC_JACOBIAN g_precomp[EC_WNAF_TABLE_SIZE];
+ assert(wNAF_len <= OPENSSL_ARRAY_SIZE(g_wNAF));
+ const EC_JACOBIAN *g = &group->generator->raw;
+ if (g_scalar != NULL) {
+ ec_compute_wNAF(group, g_wNAF, g_scalar, bits, EC_WNAF_WINDOW_BITS);
+ compute_precomp(group, g_precomp, g, EC_WNAF_TABLE_SIZE);
+ }
+
+ for (size_t i = 0; i < num; i++) {
+ assert(wNAF_len <= OPENSSL_ARRAY_SIZE(wNAF[i]));
+ ec_compute_wNAF(group, wNAF[i], &scalars[i], bits, EC_WNAF_WINDOW_BITS);
+ compute_precomp(group, precomp[i], &points[i], EC_WNAF_TABLE_SIZE);
+ }
+
+ EC_JACOBIAN tmp;
+ int r_is_at_infinity = 1;
+ for (size_t k = wNAF_len - 1; k < wNAF_len; k--) {
+ if (!r_is_at_infinity) {
+ ec_GFp_mont_dbl(group, r, r);
+ }
+
+ if (g_scalar != NULL && g_wNAF[k] != 0) {
+ lookup_precomp(group, &tmp, g_precomp, g_wNAF[k]);
+ if (r_is_at_infinity) {
+ ec_GFp_simple_point_copy(r, &tmp);
+ r_is_at_infinity = 0;
+ } else {
+ ec_GFp_mont_add(group, r, r, &tmp);
+ }
+ }
+
+ for (size_t i = 0; i < num; i++) {
+ if (wNAF[i][k] != 0) {
+ lookup_precomp(group, &tmp, precomp[i], wNAF[i][k]);
+ if (r_is_at_infinity) {
+ ec_GFp_simple_point_copy(r, &tmp);
+ r_is_at_infinity = 0;
+ } else {
+ ec_GFp_mont_add(group, r, r, &tmp);
+ }
+ }
+ }
+ }
+
+ if (r_is_at_infinity) {
+ ec_GFp_simple_point_set_to_infinity(group, r);
+ }
+
+ ret = 1;
+
+err:
+ OPENSSL_free(wNAF_alloc);
+ OPENSSL_free(precomp_alloc);
+ return ret;
+}