OpenSSL 1.1.1-pre2
This commit is contained in:
@@ -233,7 +233,7 @@ __ecp_nistz256_add:
|
||||
@ if a+b >= modulus, subtract modulus.
|
||||
@
|
||||
@ But since comparison implies subtraction, we subtract
|
||||
@ modulus and then add it back if subraction borrowed.
|
||||
@ modulus and then add it back if subtraction borrowed.
|
||||
|
||||
subs $a0,$a0,#-1
|
||||
sbcs $a1,$a1,#-1
|
||||
@@ -1222,7 +1222,7 @@ __ecp_nistz256_add_self:
|
||||
@ if a+b >= modulus, subtract modulus.
|
||||
@
|
||||
@ But since comparison implies subtraction, we subtract
|
||||
@ modulus and then add it back if subraction borrowed.
|
||||
@ modulus and then add it back if subtraction borrowed.
|
||||
|
||||
subs $a0,$a0,#-1
|
||||
sbcs $a1,$a1,#-1
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#! /usr/bin/env perl
|
||||
# Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
# Copyright 2015-2018 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
|
||||
@@ -663,7 +663,7 @@ __ecp_nistz256_div_by_2:
|
||||
adc $ap,xzr,xzr // zap $ap
|
||||
tst $acc0,#1 // is a even?
|
||||
|
||||
csel $acc0,$acc0,$t0,eq // ret = even ? a : a+modulus
|
||||
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
|
||||
|
||||
@@ -1,39 +1,19 @@
|
||||
#! /usr/bin/env perl
|
||||
# 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
|
||||
|
||||
|
||||
##############################################################################
|
||||
# #
|
||||
# Copyright 2014 Intel Corporation #
|
||||
# #
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); #
|
||||
# you may not use this file except in compliance with the License. #
|
||||
# You may obtain a copy of the License at #
|
||||
# #
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 #
|
||||
# #
|
||||
# Unless required by applicable law or agreed to in writing, software #
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, #
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
||||
# See the License for the specific language governing permissions and #
|
||||
# limitations under the License. #
|
||||
# #
|
||||
##############################################################################
|
||||
# #
|
||||
# Developers and authors: #
|
||||
# Shay Gueron (1, 2), and Vlad Krasnov (1) #
|
||||
# (1) Intel Corporation, Israel Development Center #
|
||||
# (2) University of Haifa #
|
||||
# Reference: #
|
||||
# S.Gueron and V.Krasnov, "Fast Prime Field Elliptic Curve Cryptography with#
|
||||
# 256 Bit Primes" #
|
||||
# #
|
||||
##############################################################################
|
||||
#
|
||||
# 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"
|
||||
|
||||
$flavour = shift;
|
||||
$output = shift;
|
||||
@@ -157,7 +137,7 @@ ___
|
||||
|
||||
{
|
||||
# This function receives a pointer to an array of four affine points
|
||||
# (X, Y, <1>) and rearanges the data for AVX2 execution, while
|
||||
# (X, Y, <1>) and rearranges the data for AVX2 execution, while
|
||||
# converting it to 2^29 radix redundant form
|
||||
|
||||
my ($X0,$X1,$X2,$X3, $Y0,$Y1,$Y2,$Y3,
|
||||
@@ -309,7 +289,7 @@ ___
|
||||
{
|
||||
################################################################################
|
||||
# This function receives a pointer to an array of four AVX2 formatted points
|
||||
# (X, Y, Z) convert the data to normal representation, and rearanges the data
|
||||
# (X, Y, Z) convert the data to normal representation, and rearranges the data
|
||||
|
||||
my ($D0,$D1,$D2,$D3, $D4,$D5,$D6,$D7, $D8)=map("%ymm$_",(0..8));
|
||||
my ($T0,$T1,$T2,$T3, $T4,$T5,$T6)=map("%ymm$_",(9..15));
|
||||
|
||||
Executable
+2382
@@ -0,0 +1,2382 @@
|
||||
#! /usr/bin/env perl
|
||||
# Copyright 2016 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 PPC64.
|
||||
#
|
||||
# August 2016.
|
||||
#
|
||||
# Original ECP_NISTZ256 submission targeting x86_64 is detailed in
|
||||
# http://eprint.iacr.org/2013/816.
|
||||
#
|
||||
# with/without -DECP_NISTZ256_ASM
|
||||
# POWER7 +260-530%
|
||||
# POWER8 +220-340%
|
||||
|
||||
$flavour = shift;
|
||||
while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {}
|
||||
|
||||
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
|
||||
( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
|
||||
( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
|
||||
die "can't locate ppc-xlate.pl";
|
||||
|
||||
open OUT,"| \"$^X\" $xlate $flavour $output";
|
||||
*STDOUT=*OUT;
|
||||
|
||||
my $sp="r1";
|
||||
|
||||
{
|
||||
my ($rp,$ap,$bp,$bi,$acc0,$acc1,$acc2,$acc3,$poly1,$poly3,
|
||||
$acc4,$acc5,$a0,$a1,$a2,$a3,$t0,$t1,$t2,$t3) =
|
||||
map("r$_",(3..12,22..31));
|
||||
|
||||
my ($acc6,$acc7)=($bp,$bi); # used in __ecp_nistz256_sqr_mont
|
||||
|
||||
$code.=<<___;
|
||||
.machine "any"
|
||||
.text
|
||||
___
|
||||
########################################################################
|
||||
# Convert ecp_nistz256_table.c to layout expected by ecp_nistz_gather_w7
|
||||
#
|
||||
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
|
||||
open TABLE,"<ecp_nistz256_table.c" or
|
||||
open TABLE,"<${dir}../ecp_nistz256_table.c" or
|
||||
die "failed to open ecp_nistz256_table.c:",$!;
|
||||
|
||||
use integer;
|
||||
|
||||
foreach(<TABLE>) {
|
||||
s/TOBN\(\s*(0x[0-9a-f]+),\s*(0x[0-9a-f]+)\s*\)/push @arr,hex($2),hex($1)/geo;
|
||||
}
|
||||
close TABLE;
|
||||
|
||||
# See ecp_nistz256_table.c for explanation for why it's 64*16*37.
|
||||
# 64*16*37-1 is because $#arr returns last valid index or @arr, not
|
||||
# amount of elements.
|
||||
die "insane number of elements" if ($#arr != 64*16*37-1);
|
||||
|
||||
$code.=<<___;
|
||||
.type ecp_nistz256_precomputed,\@object
|
||||
.globl ecp_nistz256_precomputed
|
||||
.align 12
|
||||
ecp_nistz256_precomputed:
|
||||
___
|
||||
########################################################################
|
||||
# this conversion smashes P256_POINT_AFFINE by individual bytes with
|
||||
# 64 byte interval, similar to
|
||||
# 1111222233334444
|
||||
# 1234123412341234
|
||||
for(1..37) {
|
||||
@tbl = splice(@arr,0,64*16);
|
||||
for($i=0;$i<64;$i++) {
|
||||
undef @line;
|
||||
for($j=0;$j<64;$j++) {
|
||||
push @line,(@tbl[$j*16+$i/4]>>(($i%4)*8))&0xff;
|
||||
}
|
||||
$code.=".byte\t";
|
||||
$code.=join(',',map { sprintf "0x%02x",$_} @line);
|
||||
$code.="\n";
|
||||
}
|
||||
}
|
||||
|
||||
$code.=<<___;
|
||||
.size ecp_nistz256_precomputed,.-ecp_nistz256_precomputed
|
||||
.asciz "ECP_NISTZ256 for PPC64, CRYPTOGAMS by <appro\@openssl.org>"
|
||||
|
||||
# void ecp_nistz256_mul_mont(BN_ULONG x0[4],const BN_ULONG x1[4],
|
||||
# const BN_ULONG x2[4]);
|
||||
.globl ecp_nistz256_mul_mont
|
||||
.align 5
|
||||
ecp_nistz256_mul_mont:
|
||||
stdu $sp,-128($sp)
|
||||
mflr r0
|
||||
std r22,48($sp)
|
||||
std r23,56($sp)
|
||||
std r24,64($sp)
|
||||
std r25,72($sp)
|
||||
std r26,80($sp)
|
||||
std r27,88($sp)
|
||||
std r28,96($sp)
|
||||
std r29,104($sp)
|
||||
std r30,112($sp)
|
||||
std r31,120($sp)
|
||||
|
||||
ld $a0,0($ap)
|
||||
ld $bi,0($bp)
|
||||
ld $a1,8($ap)
|
||||
ld $a2,16($ap)
|
||||
ld $a3,24($ap)
|
||||
|
||||
li $poly1,-1
|
||||
srdi $poly1,$poly1,32 # 0x00000000ffffffff
|
||||
li $poly3,1
|
||||
orc $poly3,$poly3,$poly1 # 0xffffffff00000001
|
||||
|
||||
bl __ecp_nistz256_mul_mont
|
||||
|
||||
mtlr r0
|
||||
ld r22,48($sp)
|
||||
ld r23,56($sp)
|
||||
ld r24,64($sp)
|
||||
ld r25,72($sp)
|
||||
ld r26,80($sp)
|
||||
ld r27,88($sp)
|
||||
ld r28,96($sp)
|
||||
ld r29,104($sp)
|
||||
ld r30,112($sp)
|
||||
ld r31,120($sp)
|
||||
addi $sp,$sp,128
|
||||
blr
|
||||
.long 0
|
||||
.byte 0,12,4,0,0x80,10,3,0
|
||||
.long 0
|
||||
.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
|
||||
.align 4
|
||||
ecp_nistz256_sqr_mont:
|
||||
stdu $sp,-128($sp)
|
||||
mflr r0
|
||||
std r22,48($sp)
|
||||
std r23,56($sp)
|
||||
std r24,64($sp)
|
||||
std r25,72($sp)
|
||||
std r26,80($sp)
|
||||
std r27,88($sp)
|
||||
std r28,96($sp)
|
||||
std r29,104($sp)
|
||||
std r30,112($sp)
|
||||
std r31,120($sp)
|
||||
|
||||
ld $a0,0($ap)
|
||||
ld $a1,8($ap)
|
||||
ld $a2,16($ap)
|
||||
ld $a3,24($ap)
|
||||
|
||||
li $poly1,-1
|
||||
srdi $poly1,$poly1,32 # 0x00000000ffffffff
|
||||
li $poly3,1
|
||||
orc $poly3,$poly3,$poly1 # 0xffffffff00000001
|
||||
|
||||
bl __ecp_nistz256_sqr_mont
|
||||
|
||||
mtlr r0
|
||||
ld r22,48($sp)
|
||||
ld r23,56($sp)
|
||||
ld r24,64($sp)
|
||||
ld r25,72($sp)
|
||||
ld r26,80($sp)
|
||||
ld r27,88($sp)
|
||||
ld r28,96($sp)
|
||||
ld r29,104($sp)
|
||||
ld r30,112($sp)
|
||||
ld r31,120($sp)
|
||||
addi $sp,$sp,128
|
||||
blr
|
||||
.long 0
|
||||
.byte 0,12,4,0,0x80,10,2,0
|
||||
.long 0
|
||||
.size ecp_nistz256_sqr_mont,.-ecp_nistz256_sqr_mont
|
||||
|
||||
# void ecp_nistz256_add(BN_ULONG x0[4],const BN_ULONG x1[4],
|
||||
# const BN_ULONG x2[4]);
|
||||
.globl ecp_nistz256_add
|
||||
.align 4
|
||||
ecp_nistz256_add:
|
||||
stdu $sp,-128($sp)
|
||||
mflr r0
|
||||
std r28,96($sp)
|
||||
std r29,104($sp)
|
||||
std r30,112($sp)
|
||||
std r31,120($sp)
|
||||
|
||||
ld $acc0,0($ap)
|
||||
ld $t0, 0($bp)
|
||||
ld $acc1,8($ap)
|
||||
ld $t1, 8($bp)
|
||||
ld $acc2,16($ap)
|
||||
ld $t2, 16($bp)
|
||||
ld $acc3,24($ap)
|
||||
ld $t3, 24($bp)
|
||||
|
||||
li $poly1,-1
|
||||
srdi $poly1,$poly1,32 # 0x00000000ffffffff
|
||||
li $poly3,1
|
||||
orc $poly3,$poly3,$poly1 # 0xffffffff00000001
|
||||
|
||||
bl __ecp_nistz256_add
|
||||
|
||||
mtlr r0
|
||||
ld r28,96($sp)
|
||||
ld r29,104($sp)
|
||||
ld r30,112($sp)
|
||||
ld r31,120($sp)
|
||||
addi $sp,$sp,128
|
||||
blr
|
||||
.long 0
|
||||
.byte 0,12,4,0,0x80,4,3,0
|
||||
.long 0
|
||||
.size ecp_nistz256_add,.-ecp_nistz256_add
|
||||
|
||||
# void ecp_nistz256_div_by_2(BN_ULONG x0[4],const BN_ULONG x1[4]);
|
||||
.globl ecp_nistz256_div_by_2
|
||||
.align 4
|
||||
ecp_nistz256_div_by_2:
|
||||
stdu $sp,-128($sp)
|
||||
mflr r0
|
||||
std r28,96($sp)
|
||||
std r29,104($sp)
|
||||
std r30,112($sp)
|
||||
std r31,120($sp)
|
||||
|
||||
ld $acc0,0($ap)
|
||||
ld $acc1,8($ap)
|
||||
ld $acc2,16($ap)
|
||||
ld $acc3,24($ap)
|
||||
|
||||
li $poly1,-1
|
||||
srdi $poly1,$poly1,32 # 0x00000000ffffffff
|
||||
li $poly3,1
|
||||
orc $poly3,$poly3,$poly1 # 0xffffffff00000001
|
||||
|
||||
bl __ecp_nistz256_div_by_2
|
||||
|
||||
mtlr r0
|
||||
ld r28,96($sp)
|
||||
ld r29,104($sp)
|
||||
ld r30,112($sp)
|
||||
ld r31,120($sp)
|
||||
addi $sp,$sp,128
|
||||
blr
|
||||
.long 0
|
||||
.byte 0,12,4,0,0x80,4,2,0
|
||||
.long 0
|
||||
.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
|
||||
.align 4
|
||||
ecp_nistz256_mul_by_2:
|
||||
stdu $sp,-128($sp)
|
||||
mflr r0
|
||||
std r28,96($sp)
|
||||
std r29,104($sp)
|
||||
std r30,112($sp)
|
||||
std r31,120($sp)
|
||||
|
||||
ld $acc0,0($ap)
|
||||
ld $acc1,8($ap)
|
||||
ld $acc2,16($ap)
|
||||
ld $acc3,24($ap)
|
||||
|
||||
mr $t0,$acc0
|
||||
mr $t1,$acc1
|
||||
mr $t2,$acc2
|
||||
mr $t3,$acc3
|
||||
|
||||
li $poly1,-1
|
||||
srdi $poly1,$poly1,32 # 0x00000000ffffffff
|
||||
li $poly3,1
|
||||
orc $poly3,$poly3,$poly1 # 0xffffffff00000001
|
||||
|
||||
bl __ecp_nistz256_add # ret = a+a // 2*a
|
||||
|
||||
mtlr r0
|
||||
ld r28,96($sp)
|
||||
ld r29,104($sp)
|
||||
ld r30,112($sp)
|
||||
ld r31,120($sp)
|
||||
addi $sp,$sp,128
|
||||
blr
|
||||
.long 0
|
||||
.byte 0,12,4,0,0x80,4,3,0
|
||||
.long 0
|
||||
.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
|
||||
.align 4
|
||||
ecp_nistz256_mul_by_3:
|
||||
stdu $sp,-128($sp)
|
||||
mflr r0
|
||||
std r28,96($sp)
|
||||
std r29,104($sp)
|
||||
std r30,112($sp)
|
||||
std r31,120($sp)
|
||||
|
||||
ld $acc0,0($ap)
|
||||
ld $acc1,8($ap)
|
||||
ld $acc2,16($ap)
|
||||
ld $acc3,24($ap)
|
||||
|
||||
mr $t0,$acc0
|
||||
std $acc0,64($sp)
|
||||
mr $t1,$acc1
|
||||
std $acc1,72($sp)
|
||||
mr $t2,$acc2
|
||||
std $acc2,80($sp)
|
||||
mr $t3,$acc3
|
||||
std $acc3,88($sp)
|
||||
|
||||
li $poly1,-1
|
||||
srdi $poly1,$poly1,32 # 0x00000000ffffffff
|
||||
li $poly3,1
|
||||
orc $poly3,$poly3,$poly1 # 0xffffffff00000001
|
||||
|
||||
bl __ecp_nistz256_add # ret = a+a // 2*a
|
||||
|
||||
ld $t0,64($sp)
|
||||
ld $t1,72($sp)
|
||||
ld $t2,80($sp)
|
||||
ld $t3,88($sp)
|
||||
|
||||
bl __ecp_nistz256_add # ret += a // 2*a+a=3*a
|
||||
|
||||
mtlr r0
|
||||
ld r28,96($sp)
|
||||
ld r29,104($sp)
|
||||
ld r30,112($sp)
|
||||
ld r31,120($sp)
|
||||
addi $sp,$sp,128
|
||||
blr
|
||||
.long 0
|
||||
.byte 0,12,4,0,0x80,4,2,0
|
||||
.long 0
|
||||
.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
|
||||
.align 4
|
||||
ecp_nistz256_sub:
|
||||
stdu $sp,-128($sp)
|
||||
mflr r0
|
||||
std r28,96($sp)
|
||||
std r29,104($sp)
|
||||
std r30,112($sp)
|
||||
std r31,120($sp)
|
||||
|
||||
ld $acc0,0($ap)
|
||||
ld $acc1,8($ap)
|
||||
ld $acc2,16($ap)
|
||||
ld $acc3,24($ap)
|
||||
|
||||
li $poly1,-1
|
||||
srdi $poly1,$poly1,32 # 0x00000000ffffffff
|
||||
li $poly3,1
|
||||
orc $poly3,$poly3,$poly1 # 0xffffffff00000001
|
||||
|
||||
bl __ecp_nistz256_sub_from
|
||||
|
||||
mtlr r0
|
||||
ld r28,96($sp)
|
||||
ld r29,104($sp)
|
||||
ld r30,112($sp)
|
||||
ld r31,120($sp)
|
||||
addi $sp,$sp,128
|
||||
blr
|
||||
.long 0
|
||||
.byte 0,12,4,0,0x80,4,3,0
|
||||
.long 0
|
||||
.size ecp_nistz256_sub,.-ecp_nistz256_sub
|
||||
|
||||
# void ecp_nistz256_neg(BN_ULONG x0[4],const BN_ULONG x1[4]);
|
||||
.globl ecp_nistz256_neg
|
||||
.align 4
|
||||
ecp_nistz256_neg:
|
||||
stdu $sp,-128($sp)
|
||||
mflr r0
|
||||
std r28,96($sp)
|
||||
std r29,104($sp)
|
||||
std r30,112($sp)
|
||||
std r31,120($sp)
|
||||
|
||||
mr $bp,$ap
|
||||
li $acc0,0
|
||||
li $acc1,0
|
||||
li $acc2,0
|
||||
li $acc3,0
|
||||
|
||||
li $poly1,-1
|
||||
srdi $poly1,$poly1,32 # 0x00000000ffffffff
|
||||
li $poly3,1
|
||||
orc $poly3,$poly3,$poly1 # 0xffffffff00000001
|
||||
|
||||
bl __ecp_nistz256_sub_from
|
||||
|
||||
mtlr r0
|
||||
ld r28,96($sp)
|
||||
ld r29,104($sp)
|
||||
ld r30,112($sp)
|
||||
ld r31,120($sp)
|
||||
addi $sp,$sp,128
|
||||
blr
|
||||
.long 0
|
||||
.byte 0,12,4,0,0x80,4,2,0
|
||||
.long 0
|
||||
.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:
|
||||
mulld $acc0,$a0,$bi # a[0]*b[0]
|
||||
mulhdu $t0,$a0,$bi
|
||||
|
||||
mulld $acc1,$a1,$bi # a[1]*b[0]
|
||||
mulhdu $t1,$a1,$bi
|
||||
|
||||
mulld $acc2,$a2,$bi # a[2]*b[0]
|
||||
mulhdu $t2,$a2,$bi
|
||||
|
||||
mulld $acc3,$a3,$bi # a[3]*b[0]
|
||||
mulhdu $t3,$a3,$bi
|
||||
ld $bi,8($bp) # b[1]
|
||||
|
||||
addc $acc1,$acc1,$t0 # accumulate high parts of multiplication
|
||||
sldi $t0,$acc0,32
|
||||
adde $acc2,$acc2,$t1
|
||||
srdi $t1,$acc0,32
|
||||
adde $acc3,$acc3,$t2
|
||||
addze $acc4,$t3
|
||||
li $acc5,0
|
||||
___
|
||||
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.=<<___;
|
||||
subfc $t2,$t0,$acc0 # "*0xffff0001"
|
||||
subfe $t3,$t1,$acc0
|
||||
addc $acc0,$acc1,$t0 # +=acc[0]<<96 and omit acc[0]
|
||||
adde $acc1,$acc2,$t1
|
||||
adde $acc2,$acc3,$t2 # +=acc[0]*0xffff0001
|
||||
adde $acc3,$acc4,$t3
|
||||
addze $acc4,$acc5
|
||||
|
||||
mulld $t0,$a0,$bi # lo(a[0]*b[i])
|
||||
mulld $t1,$a1,$bi # lo(a[1]*b[i])
|
||||
mulld $t2,$a2,$bi # lo(a[2]*b[i])
|
||||
mulld $t3,$a3,$bi # lo(a[3]*b[i])
|
||||
addc $acc0,$acc0,$t0 # accumulate low parts of multiplication
|
||||
mulhdu $t0,$a0,$bi # hi(a[0]*b[i])
|
||||
adde $acc1,$acc1,$t1
|
||||
mulhdu $t1,$a1,$bi # hi(a[1]*b[i])
|
||||
adde $acc2,$acc2,$t2
|
||||
mulhdu $t2,$a2,$bi # hi(a[2]*b[i])
|
||||
adde $acc3,$acc3,$t3
|
||||
mulhdu $t3,$a3,$bi # hi(a[3]*b[i])
|
||||
addze $acc4,$acc4
|
||||
___
|
||||
$code.=<<___ if ($i<3);
|
||||
ld $bi,8*($i+1)($bp) # b[$i+1]
|
||||
___
|
||||
$code.=<<___;
|
||||
addc $acc1,$acc1,$t0 # accumulate high parts of multiplication
|
||||
sldi $t0,$acc0,32
|
||||
adde $acc2,$acc2,$t1
|
||||
srdi $t1,$acc0,32
|
||||
adde $acc3,$acc3,$t2
|
||||
adde $acc4,$acc4,$t3
|
||||
li $acc5,0
|
||||
addze $acc5,$acc5
|
||||
___
|
||||
}
|
||||
$code.=<<___;
|
||||
# last reduction
|
||||
subfc $t2,$t0,$acc0 # "*0xffff0001"
|
||||
subfe $t3,$t1,$acc0
|
||||
addc $acc0,$acc1,$t0 # +=acc[0]<<96 and omit acc[0]
|
||||
adde $acc1,$acc2,$t1
|
||||
adde $acc2,$acc3,$t2 # +=acc[0]*0xffff0001
|
||||
adde $acc3,$acc4,$t3
|
||||
addze $acc4,$acc5
|
||||
|
||||
li $t2,0
|
||||
addic $acc0,$acc0,1 # ret -= modulus
|
||||
subfe $acc1,$poly1,$acc1
|
||||
subfe $acc2,$t2,$acc2
|
||||
subfe $acc3,$poly3,$acc3
|
||||
subfe $acc4,$t2,$acc4
|
||||
|
||||
addc $acc0,$acc0,$acc4 # ret += modulus if borrow
|
||||
and $t1,$poly1,$acc4
|
||||
and $t3,$poly3,$acc4
|
||||
adde $acc1,$acc1,$t1
|
||||
addze $acc2,$acc2
|
||||
adde $acc3,$acc3,$t3
|
||||
|
||||
std $acc0,0($rp)
|
||||
std $acc1,8($rp)
|
||||
std $acc2,16($rp)
|
||||
std $acc3,24($rp)
|
||||
|
||||
blr
|
||||
.long 0
|
||||
.byte 0,12,0x14,0,0,0,1,0
|
||||
.long 0
|
||||
.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.
|
||||
|
||||
mulld $acc1,$a1,$a0 # a[1]*a[0]
|
||||
mulhdu $t1,$a1,$a0
|
||||
mulld $acc2,$a2,$a0 # a[2]*a[0]
|
||||
mulhdu $t2,$a2,$a0
|
||||
mulld $acc3,$a3,$a0 # a[3]*a[0]
|
||||
mulhdu $acc4,$a3,$a0
|
||||
|
||||
addc $acc2,$acc2,$t1 # accumulate high parts of multiplication
|
||||
mulld $t0,$a2,$a1 # a[2]*a[1]
|
||||
mulhdu $t1,$a2,$a1
|
||||
adde $acc3,$acc3,$t2
|
||||
mulld $t2,$a3,$a1 # a[3]*a[1]
|
||||
mulhdu $t3,$a3,$a1
|
||||
addze $acc4,$acc4 # can't overflow
|
||||
|
||||
mulld $acc5,$a3,$a2 # a[3]*a[2]
|
||||
mulhdu $acc6,$a3,$a2
|
||||
|
||||
addc $t1,$t1,$t2 # accumulate high parts of multiplication
|
||||
addze $t2,$t3 # can't overflow
|
||||
|
||||
addc $acc3,$acc3,$t0 # accumulate low parts of multiplication
|
||||
adde $acc4,$acc4,$t1
|
||||
adde $acc5,$acc5,$t2
|
||||
addze $acc6,$acc6 # can't overflow
|
||||
|
||||
addc $acc1,$acc1,$acc1 # acc[1-6]*=2
|
||||
adde $acc2,$acc2,$acc2
|
||||
adde $acc3,$acc3,$acc3
|
||||
adde $acc4,$acc4,$acc4
|
||||
adde $acc5,$acc5,$acc5
|
||||
adde $acc6,$acc6,$acc6
|
||||
li $acc7,0
|
||||
addze $acc7,$acc7
|
||||
|
||||
mulld $acc0,$a0,$a0 # a[0]*a[0]
|
||||
mulhdu $a0,$a0,$a0
|
||||
mulld $t1,$a1,$a1 # a[1]*a[1]
|
||||
mulhdu $a1,$a1,$a1
|
||||
mulld $t2,$a2,$a2 # a[2]*a[2]
|
||||
mulhdu $a2,$a2,$a2
|
||||
mulld $t3,$a3,$a3 # a[3]*a[3]
|
||||
mulhdu $a3,$a3,$a3
|
||||
addc $acc1,$acc1,$a0 # +a[i]*a[i]
|
||||
sldi $t0,$acc0,32
|
||||
adde $acc2,$acc2,$t1
|
||||
srdi $t1,$acc0,32
|
||||
adde $acc3,$acc3,$a1
|
||||
adde $acc4,$acc4,$t2
|
||||
adde $acc5,$acc5,$a2
|
||||
adde $acc6,$acc6,$t3
|
||||
adde $acc7,$acc7,$a3
|
||||
___
|
||||
for($i=0;$i<3;$i++) { # reductions, see commentary in
|
||||
# multiplication for details
|
||||
$code.=<<___;
|
||||
subfc $t2,$t0,$acc0 # "*0xffff0001"
|
||||
subfe $t3,$t1,$acc0
|
||||
addc $acc0,$acc1,$t0 # +=acc[0]<<96 and omit acc[0]
|
||||
sldi $t0,$acc0,32
|
||||
adde $acc1,$acc2,$t1
|
||||
srdi $t1,$acc0,32
|
||||
adde $acc2,$acc3,$t2 # +=acc[0]*0xffff0001
|
||||
addze $acc3,$t3 # can't overflow
|
||||
___
|
||||
}
|
||||
$code.=<<___;
|
||||
subfc $t2,$t0,$acc0 # "*0xffff0001"
|
||||
subfe $t3,$t1,$acc0
|
||||
addc $acc0,$acc1,$t0 # +=acc[0]<<96 and omit acc[0]
|
||||
adde $acc1,$acc2,$t1
|
||||
adde $acc2,$acc3,$t2 # +=acc[0]*0xffff0001
|
||||
addze $acc3,$t3 # can't overflow
|
||||
|
||||
addc $acc0,$acc0,$acc4 # accumulate upper half
|
||||
adde $acc1,$acc1,$acc5
|
||||
adde $acc2,$acc2,$acc6
|
||||
adde $acc3,$acc3,$acc7
|
||||
li $t2,0
|
||||
addze $acc4,$t2
|
||||
|
||||
addic $acc0,$acc0,1 # ret -= modulus
|
||||
subfe $acc1,$poly1,$acc1
|
||||
subfe $acc2,$t2,$acc2
|
||||
subfe $acc3,$poly3,$acc3
|
||||
subfe $acc4,$t2,$acc4
|
||||
|
||||
addc $acc0,$acc0,$acc4 # ret += modulus if borrow
|
||||
and $t1,$poly1,$acc4
|
||||
and $t3,$poly3,$acc4
|
||||
adde $acc1,$acc1,$t1
|
||||
addze $acc2,$acc2
|
||||
adde $acc3,$acc3,$t3
|
||||
|
||||
std $acc0,0($rp)
|
||||
std $acc1,8($rp)
|
||||
std $acc2,16($rp)
|
||||
std $acc3,24($rp)
|
||||
|
||||
blr
|
||||
.long 0
|
||||
.byte 0,12,0x14,0,0,0,1,0
|
||||
.long 0
|
||||
.size __ecp_nistz256_sqr_mont,.-__ecp_nistz256_sqr_mont
|
||||
|
||||
# Note that __ecp_nistz256_add 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,\@function
|
||||
.align 4
|
||||
__ecp_nistz256_add:
|
||||
addc $acc0,$acc0,$t0 # ret = a+b
|
||||
adde $acc1,$acc1,$t1
|
||||
adde $acc2,$acc2,$t2
|
||||
li $t2,0
|
||||
adde $acc3,$acc3,$t3
|
||||
addze $t0,$t2
|
||||
|
||||
# if a+b >= modulus, subtract modulus
|
||||
#
|
||||
# But since comparison implies subtraction, we subtract
|
||||
# modulus and then add it back if subtraction borrowed.
|
||||
|
||||
subic $acc0,$acc0,-1
|
||||
subfe $acc1,$poly1,$acc1
|
||||
subfe $acc2,$t2,$acc2
|
||||
subfe $acc3,$poly3,$acc3
|
||||
subfe $t0,$t2,$t0
|
||||
|
||||
addc $acc0,$acc0,$t0
|
||||
and $t1,$poly1,$t0
|
||||
and $t3,$poly3,$t0
|
||||
adde $acc1,$acc1,$t1
|
||||
addze $acc2,$acc2
|
||||
adde $acc3,$acc3,$t3
|
||||
|
||||
std $acc0,0($rp)
|
||||
std $acc1,8($rp)
|
||||
std $acc2,16($rp)
|
||||
std $acc3,24($rp)
|
||||
|
||||
blr
|
||||
.long 0
|
||||
.byte 0,12,0x14,0,0,0,3,0
|
||||
.long 0
|
||||
.size __ecp_nistz256_add,.-__ecp_nistz256_add
|
||||
|
||||
.type __ecp_nistz256_sub_from,\@function
|
||||
.align 4
|
||||
__ecp_nistz256_sub_from:
|
||||
ld $t0,0($bp)
|
||||
ld $t1,8($bp)
|
||||
ld $t2,16($bp)
|
||||
ld $t3,24($bp)
|
||||
subfc $acc0,$t0,$acc0 # ret = a-b
|
||||
subfe $acc1,$t1,$acc1
|
||||
subfe $acc2,$t2,$acc2
|
||||
subfe $acc3,$t3,$acc3
|
||||
subfe $t0,$t0,$t0 # t0 = borrow ? -1 : 0
|
||||
|
||||
# if a-b borrowed, add modulus
|
||||
|
||||
addc $acc0,$acc0,$t0 # ret -= modulus & t0
|
||||
and $t1,$poly1,$t0
|
||||
and $t3,$poly3,$t0
|
||||
adde $acc1,$acc1,$t1
|
||||
addze $acc2,$acc2
|
||||
adde $acc3,$acc3,$t3
|
||||
|
||||
std $acc0,0($rp)
|
||||
std $acc1,8($rp)
|
||||
std $acc2,16($rp)
|
||||
std $acc3,24($rp)
|
||||
|
||||
blr
|
||||
.long 0
|
||||
.byte 0,12,0x14,0,0,0,3,0
|
||||
.long 0
|
||||
.size __ecp_nistz256_sub_from,.-__ecp_nistz256_sub_from
|
||||
|
||||
.type __ecp_nistz256_sub_morf,\@function
|
||||
.align 4
|
||||
__ecp_nistz256_sub_morf:
|
||||
ld $t0,0($bp)
|
||||
ld $t1,8($bp)
|
||||
ld $t2,16($bp)
|
||||
ld $t3,24($bp)
|
||||
subfc $acc0,$acc0,$t0 # ret = b-a
|
||||
subfe $acc1,$acc1,$t1
|
||||
subfe $acc2,$acc2,$t2
|
||||
subfe $acc3,$acc3,$t3
|
||||
subfe $t0,$t0,$t0 # t0 = borrow ? -1 : 0
|
||||
|
||||
# if b-a borrowed, add modulus
|
||||
|
||||
addc $acc0,$acc0,$t0 # ret -= modulus & t0
|
||||
and $t1,$poly1,$t0
|
||||
and $t3,$poly3,$t0
|
||||
adde $acc1,$acc1,$t1
|
||||
addze $acc2,$acc2
|
||||
adde $acc3,$acc3,$t3
|
||||
|
||||
std $acc0,0($rp)
|
||||
std $acc1,8($rp)
|
||||
std $acc2,16($rp)
|
||||
std $acc3,24($rp)
|
||||
|
||||
blr
|
||||
.long 0
|
||||
.byte 0,12,0x14,0,0,0,3,0
|
||||
.long 0
|
||||
.size __ecp_nistz256_sub_morf,.-__ecp_nistz256_sub_morf
|
||||
|
||||
.type __ecp_nistz256_div_by_2,\@function
|
||||
.align 4
|
||||
__ecp_nistz256_div_by_2:
|
||||
andi. $t0,$acc0,1
|
||||
addic $acc0,$acc0,-1 # a += modulus
|
||||
neg $t0,$t0
|
||||
adde $acc1,$acc1,$poly1
|
||||
not $t0,$t0
|
||||
addze $acc2,$acc2
|
||||
li $t2,0
|
||||
adde $acc3,$acc3,$poly3
|
||||
and $t1,$poly1,$t0
|
||||
addze $ap,$t2 # ap = carry
|
||||
and $t3,$poly3,$t0
|
||||
|
||||
subfc $acc0,$t0,$acc0 # a -= modulus if a was even
|
||||
subfe $acc1,$t1,$acc1
|
||||
subfe $acc2,$t2,$acc2
|
||||
subfe $acc3,$t3,$acc3
|
||||
subfe $ap, $t2,$ap
|
||||
|
||||
srdi $acc0,$acc0,1
|
||||
sldi $t0,$acc1,63
|
||||
srdi $acc1,$acc1,1
|
||||
sldi $t1,$acc2,63
|
||||
srdi $acc2,$acc2,1
|
||||
sldi $t2,$acc3,63
|
||||
srdi $acc3,$acc3,1
|
||||
sldi $t3,$ap,63
|
||||
or $acc0,$acc0,$t0
|
||||
or $acc1,$acc1,$t1
|
||||
or $acc2,$acc2,$t2
|
||||
or $acc3,$acc3,$t3
|
||||
|
||||
std $acc0,0($rp)
|
||||
std $acc1,8($rp)
|
||||
std $acc2,16($rp)
|
||||
std $acc3,24($rp)
|
||||
|
||||
blr
|
||||
.long 0
|
||||
.byte 0,12,0x14,0,0,0,1,0
|
||||
.long 0
|
||||
.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);
|
||||
#
|
||||
if (1) {
|
||||
my $FRAME=64+32*4+12*8;
|
||||
my ($S,$M,$Zsqr,$tmp0)=map(64+32*$_,(0..3));
|
||||
# above map() describes stack layout with 4 temporary
|
||||
# 256-bit vectors on top.
|
||||
my ($rp_real,$ap_real) = map("r$_",(20,21));
|
||||
|
||||
$code.=<<___;
|
||||
.globl ecp_nistz256_point_double
|
||||
.align 5
|
||||
ecp_nistz256_point_double:
|
||||
stdu $sp,-$FRAME($sp)
|
||||
mflr r0
|
||||
std r20,$FRAME-8*12($sp)
|
||||
std r21,$FRAME-8*11($sp)
|
||||
std r22,$FRAME-8*10($sp)
|
||||
std r23,$FRAME-8*9($sp)
|
||||
std r24,$FRAME-8*8($sp)
|
||||
std r25,$FRAME-8*7($sp)
|
||||
std r26,$FRAME-8*6($sp)
|
||||
std r27,$FRAME-8*5($sp)
|
||||
std r28,$FRAME-8*4($sp)
|
||||
std r29,$FRAME-8*3($sp)
|
||||
std r30,$FRAME-8*2($sp)
|
||||
std r31,$FRAME-8*1($sp)
|
||||
|
||||
li $poly1,-1
|
||||
srdi $poly1,$poly1,32 # 0x00000000ffffffff
|
||||
li $poly3,1
|
||||
orc $poly3,$poly3,$poly1 # 0xffffffff00000001
|
||||
.Ldouble_shortcut:
|
||||
ld $acc0,32($ap)
|
||||
ld $acc1,40($ap)
|
||||
ld $acc2,48($ap)
|
||||
ld $acc3,56($ap)
|
||||
mr $t0,$acc0
|
||||
mr $t1,$acc1
|
||||
mr $t2,$acc2
|
||||
mr $t3,$acc3
|
||||
ld $a0,64($ap) # forward load for p256_sqr_mont
|
||||
ld $a1,72($ap)
|
||||
ld $a2,80($ap)
|
||||
ld $a3,88($ap)
|
||||
mr $rp_real,$rp
|
||||
mr $ap_real,$ap
|
||||
addi $rp,$sp,$S
|
||||
bl __ecp_nistz256_add # p256_mul_by_2(S, in_y);
|
||||
|
||||
addi $rp,$sp,$Zsqr
|
||||
bl __ecp_nistz256_sqr_mont # p256_sqr_mont(Zsqr, in_z);
|
||||
|
||||
ld $t0,0($ap_real)
|
||||
ld $t1,8($ap_real)
|
||||
ld $t2,16($ap_real)
|
||||
ld $t3,24($ap_real)
|
||||
mr $a0,$acc0 # put Zsqr aside for p256_sub
|
||||
mr $a1,$acc1
|
||||
mr $a2,$acc2
|
||||
mr $a3,$acc3
|
||||
addi $rp,$sp,$M
|
||||
bl __ecp_nistz256_add # p256_add(M, Zsqr, in_x);
|
||||
|
||||
addi $bp,$ap_real,0
|
||||
mr $acc0,$a0 # restore Zsqr
|
||||
mr $acc1,$a1
|
||||
mr $acc2,$a2
|
||||
mr $acc3,$a3
|
||||
ld $a0,$S+0($sp) # forward load for p256_sqr_mont
|
||||
ld $a1,$S+8($sp)
|
||||
ld $a2,$S+16($sp)
|
||||
ld $a3,$S+24($sp)
|
||||
addi $rp,$sp,$Zsqr
|
||||
bl __ecp_nistz256_sub_morf # p256_sub(Zsqr, in_x, Zsqr);
|
||||
|
||||
addi $rp,$sp,$S
|
||||
bl __ecp_nistz256_sqr_mont # p256_sqr_mont(S, S);
|
||||
|
||||
ld $bi,32($ap_real)
|
||||
ld $a0,64($ap_real)
|
||||
ld $a1,72($ap_real)
|
||||
ld $a2,80($ap_real)
|
||||
ld $a3,88($ap_real)
|
||||
addi $bp,$ap_real,32
|
||||
addi $rp,$sp,$tmp0
|
||||
bl __ecp_nistz256_mul_mont # p256_mul_mont(tmp0, in_z, in_y);
|
||||
|
||||
mr $t0,$acc0
|
||||
mr $t1,$acc1
|
||||
mr $t2,$acc2
|
||||
mr $t3,$acc3
|
||||
ld $a0,$S+0($sp) # forward load for p256_sqr_mont
|
||||
ld $a1,$S+8($sp)
|
||||
ld $a2,$S+16($sp)
|
||||
ld $a3,$S+24($sp)
|
||||
addi $rp,$rp_real,64
|
||||
bl __ecp_nistz256_add # p256_mul_by_2(res_z, tmp0);
|
||||
|
||||
addi $rp,$sp,$tmp0
|
||||
bl __ecp_nistz256_sqr_mont # p256_sqr_mont(tmp0, S);
|
||||
|
||||
ld $bi,$Zsqr($sp) # forward load for p256_mul_mont
|
||||
ld $a0,$M+0($sp)
|
||||
ld $a1,$M+8($sp)
|
||||
ld $a2,$M+16($sp)
|
||||
ld $a3,$M+24($sp)
|
||||
addi $rp,$rp_real,32
|
||||
bl __ecp_nistz256_div_by_2 # p256_div_by_2(res_y, tmp0);
|
||||
|
||||
addi $bp,$sp,$Zsqr
|
||||
addi $rp,$sp,$M
|
||||
bl __ecp_nistz256_mul_mont # p256_mul_mont(M, M, Zsqr);
|
||||
|
||||
mr $t0,$acc0 # duplicate M
|
||||
mr $t1,$acc1
|
||||
mr $t2,$acc2
|
||||
mr $t3,$acc3
|
||||
mr $a0,$acc0 # put M aside
|
||||
mr $a1,$acc1
|
||||
mr $a2,$acc2
|
||||
mr $a3,$acc3
|
||||
addi $rp,$sp,$M
|
||||
bl __ecp_nistz256_add
|
||||
mr $t0,$a0 # restore M
|
||||
mr $t1,$a1
|
||||
mr $t2,$a2
|
||||
mr $t3,$a3
|
||||
ld $bi,0($ap_real) # forward load for p256_mul_mont
|
||||
ld $a0,$S+0($sp)
|
||||
ld $a1,$S+8($sp)
|
||||
ld $a2,$S+16($sp)
|
||||
ld $a3,$S+24($sp)
|
||||
bl __ecp_nistz256_add # p256_mul_by_3(M, M);
|
||||
|
||||
addi $bp,$ap_real,0
|
||||
addi $rp,$sp,$S
|
||||
bl __ecp_nistz256_mul_mont # p256_mul_mont(S, S, in_x);
|
||||
|
||||
mr $t0,$acc0
|
||||
mr $t1,$acc1
|
||||
mr $t2,$acc2
|
||||
mr $t3,$acc3
|
||||
ld $a0,$M+0($sp) # forward load for p256_sqr_mont
|
||||
ld $a1,$M+8($sp)
|
||||
ld $a2,$M+16($sp)
|
||||
ld $a3,$M+24($sp)
|
||||
addi $rp,$sp,$tmp0
|
||||
bl __ecp_nistz256_add # p256_mul_by_2(tmp0, S);
|
||||
|
||||
addi $rp,$rp_real,0
|
||||
bl __ecp_nistz256_sqr_mont # p256_sqr_mont(res_x, M);
|
||||
|
||||
addi $bp,$sp,$tmp0
|
||||
bl __ecp_nistz256_sub_from # p256_sub(res_x, res_x, tmp0);
|
||||
|
||||
addi $bp,$sp,$S
|
||||
addi $rp,$sp,$S
|
||||
bl __ecp_nistz256_sub_morf # p256_sub(S, S, res_x);
|
||||
|
||||
ld $bi,$M($sp)
|
||||
mr $a0,$acc0 # copy S
|
||||
mr $a1,$acc1
|
||||
mr $a2,$acc2
|
||||
mr $a3,$acc3
|
||||
addi $bp,$sp,$M
|
||||
bl __ecp_nistz256_mul_mont # p256_mul_mont(S, S, M);
|
||||
|
||||
addi $bp,$rp_real,32
|
||||
addi $rp,$rp_real,32
|
||||
bl __ecp_nistz256_sub_from # p256_sub(res_y, S, res_y);
|
||||
|
||||
mtlr r0
|
||||
ld r20,$FRAME-8*12($sp)
|
||||
ld r21,$FRAME-8*11($sp)
|
||||
ld r22,$FRAME-8*10($sp)
|
||||
ld r23,$FRAME-8*9($sp)
|
||||
ld r24,$FRAME-8*8($sp)
|
||||
ld r25,$FRAME-8*7($sp)
|
||||
ld r26,$FRAME-8*6($sp)
|
||||
ld r27,$FRAME-8*5($sp)
|
||||
ld r28,$FRAME-8*4($sp)
|
||||
ld r29,$FRAME-8*3($sp)
|
||||
ld r30,$FRAME-8*2($sp)
|
||||
ld r31,$FRAME-8*1($sp)
|
||||
addi $sp,$sp,$FRAME
|
||||
blr
|
||||
.long 0
|
||||
.byte 0,12,4,0,0x80,12,2,0
|
||||
.long 0
|
||||
.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);
|
||||
if (1) {
|
||||
my $FRAME = 64 + 32*12 + 16*8;
|
||||
my ($res_x,$res_y,$res_z,
|
||||
$H,$Hsqr,$R,$Rsqr,$Hcub,
|
||||
$U1,$U2,$S1,$S2)=map(64+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,$temp)=map("r$_",(16..21));
|
||||
|
||||
$code.=<<___;
|
||||
.globl ecp_nistz256_point_add
|
||||
.align 5
|
||||
ecp_nistz256_point_add:
|
||||
stdu $sp,-$FRAME($sp)
|
||||
mflr r0
|
||||
std r16,$FRAME-8*16($sp)
|
||||
std r17,$FRAME-8*15($sp)
|
||||
std r18,$FRAME-8*14($sp)
|
||||
std r19,$FRAME-8*13($sp)
|
||||
std r20,$FRAME-8*12($sp)
|
||||
std r21,$FRAME-8*11($sp)
|
||||
std r22,$FRAME-8*10($sp)
|
||||
std r23,$FRAME-8*9($sp)
|
||||
std r24,$FRAME-8*8($sp)
|
||||
std r25,$FRAME-8*7($sp)
|
||||
std r26,$FRAME-8*6($sp)
|
||||
std r27,$FRAME-8*5($sp)
|
||||
std r28,$FRAME-8*4($sp)
|
||||
std r29,$FRAME-8*3($sp)
|
||||
std r30,$FRAME-8*2($sp)
|
||||
std r31,$FRAME-8*1($sp)
|
||||
|
||||
li $poly1,-1
|
||||
srdi $poly1,$poly1,32 # 0x00000000ffffffff
|
||||
li $poly3,1
|
||||
orc $poly3,$poly3,$poly1 # 0xffffffff00000001
|
||||
|
||||
ld $a0,64($bp) # in2_z
|
||||
ld $a1,72($bp)
|
||||
ld $a2,80($bp)
|
||||
ld $a3,88($bp)
|
||||
mr $rp_real,$rp
|
||||
mr $ap_real,$ap
|
||||
mr $bp_real,$bp
|
||||
or $t0,$a0,$a1
|
||||
or $t2,$a2,$a3
|
||||
or $in2infty,$t0,$t2
|
||||
neg $t0,$in2infty
|
||||
or $in2infty,$in2infty,$t0
|
||||
sradi $in2infty,$in2infty,63 # !in2infty
|
||||
addi $rp,$sp,$Z2sqr
|
||||
bl __ecp_nistz256_sqr_mont # p256_sqr_mont(Z2sqr, in2_z);
|
||||
|
||||
ld $a0,64($ap_real) # in1_z
|
||||
ld $a1,72($ap_real)
|
||||
ld $a2,80($ap_real)
|
||||
ld $a3,88($ap_real)
|
||||
or $t0,$a0,$a1
|
||||
or $t2,$a2,$a3
|
||||
or $in1infty,$t0,$t2
|
||||
neg $t0,$in1infty
|
||||
or $in1infty,$in1infty,$t0
|
||||
sradi $in1infty,$in1infty,63 # !in1infty
|
||||
addi $rp,$sp,$Z1sqr
|
||||
bl __ecp_nistz256_sqr_mont # p256_sqr_mont(Z1sqr, in1_z);
|
||||
|
||||
ld $bi,64($bp_real)
|
||||
ld $a0,$Z2sqr+0($sp)
|
||||
ld $a1,$Z2sqr+8($sp)
|
||||
ld $a2,$Z2sqr+16($sp)
|
||||
ld $a3,$Z2sqr+24($sp)
|
||||
addi $bp,$bp_real,64
|
||||
addi $rp,$sp,$S1
|
||||
bl __ecp_nistz256_mul_mont # p256_mul_mont(S1, Z2sqr, in2_z);
|
||||
|
||||
ld $bi,64($ap_real)
|
||||
ld $a0,$Z1sqr+0($sp)
|
||||
ld $a1,$Z1sqr+8($sp)
|
||||
ld $a2,$Z1sqr+16($sp)
|
||||
ld $a3,$Z1sqr+24($sp)
|
||||
addi $bp,$ap_real,64
|
||||
addi $rp,$sp,$S2
|
||||
bl __ecp_nistz256_mul_mont # p256_mul_mont(S2, Z1sqr, in1_z);
|
||||
|
||||
ld $bi,32($ap_real)
|
||||
ld $a0,$S1+0($sp)
|
||||
ld $a1,$S1+8($sp)
|
||||
ld $a2,$S1+16($sp)
|
||||
ld $a3,$S1+24($sp)
|
||||
addi $bp,$ap_real,32
|
||||
addi $rp,$sp,$S1
|
||||
bl __ecp_nistz256_mul_mont # p256_mul_mont(S1, S1, in1_y);
|
||||
|
||||
ld $bi,32($bp_real)
|
||||
ld $a0,$S2+0($sp)
|
||||
ld $a1,$S2+8($sp)
|
||||
ld $a2,$S2+16($sp)
|
||||
ld $a3,$S2+24($sp)
|
||||
addi $bp,$bp_real,32
|
||||
addi $rp,$sp,$S2
|
||||
bl __ecp_nistz256_mul_mont # p256_mul_mont(S2, S2, in2_y);
|
||||
|
||||
addi $bp,$sp,$S1
|
||||
ld $bi,$Z2sqr($sp) # forward load for p256_mul_mont
|
||||
ld $a0,0($ap_real)
|
||||
ld $a1,8($ap_real)
|
||||
ld $a2,16($ap_real)
|
||||
ld $a3,24($ap_real)
|
||||
addi $rp,$sp,$R
|
||||
bl __ecp_nistz256_sub_from # p256_sub(R, S2, S1);
|
||||
|
||||
or $acc0,$acc0,$acc1 # see if result is zero
|
||||
or $acc2,$acc2,$acc3
|
||||
or $temp,$acc0,$acc2
|
||||
|
||||
addi $bp,$sp,$Z2sqr
|
||||
addi $rp,$sp,$U1
|
||||
bl __ecp_nistz256_mul_mont # p256_mul_mont(U1, in1_x, Z2sqr);
|
||||
|
||||
ld $bi,$Z1sqr($sp)
|
||||
ld $a0,0($bp_real)
|
||||
ld $a1,8($bp_real)
|
||||
ld $a2,16($bp_real)
|
||||
ld $a3,24($bp_real)
|
||||
addi $bp,$sp,$Z1sqr
|
||||
addi $rp,$sp,$U2
|
||||
bl __ecp_nistz256_mul_mont # p256_mul_mont(U2, in2_x, Z1sqr);
|
||||
|
||||
addi $bp,$sp,$U1
|
||||
ld $a0,$R+0($sp) # forward load for p256_sqr_mont
|
||||
ld $a1,$R+8($sp)
|
||||
ld $a2,$R+16($sp)
|
||||
ld $a3,$R+24($sp)
|
||||
addi $rp,$sp,$H
|
||||
bl __ecp_nistz256_sub_from # p256_sub(H, U2, U1);
|
||||
|
||||
or $acc0,$acc0,$acc1 # see if result is zero
|
||||
or $acc2,$acc2,$acc3
|
||||
or. $acc0,$acc0,$acc2
|
||||
bne .Ladd_proceed # is_equal(U1,U2)?
|
||||
|
||||
and. $t0,$in1infty,$in2infty
|
||||
beq .Ladd_proceed # (in1infty || in2infty)?
|
||||
|
||||
cmpldi $temp,0
|
||||
beq .Ladd_double # is_equal(S1,S2)?
|
||||
|
||||
xor $a0,$a0,$a0
|
||||
std $a0,0($rp_real)
|
||||
std $a0,8($rp_real)
|
||||
std $a0,16($rp_real)
|
||||
std $a0,24($rp_real)
|
||||
std $a0,32($rp_real)
|
||||
std $a0,40($rp_real)
|
||||
std $a0,48($rp_real)
|
||||
std $a0,56($rp_real)
|
||||
std $a0,64($rp_real)
|
||||
std $a0,72($rp_real)
|
||||
std $a0,80($rp_real)
|
||||
std $a0,88($rp_real)
|
||||
b .Ladd_done
|
||||
|
||||
.align 4
|
||||
.Ladd_double:
|
||||
ld $bp,0($sp) # back-link
|
||||
mr $ap,$ap_real
|
||||
mr $rp,$rp_real
|
||||
ld r16,$FRAME-8*16($sp)
|
||||
ld r17,$FRAME-8*15($sp)
|
||||
ld r18,$FRAME-8*14($sp)
|
||||
ld r19,$FRAME-8*13($sp)
|
||||
stdu $bp,$FRAME-288($sp) # difference in stack frame sizes
|
||||
b .Ldouble_shortcut
|
||||
|
||||
.align 4
|
||||
.Ladd_proceed:
|
||||
addi $rp,$sp,$Rsqr
|
||||
bl __ecp_nistz256_sqr_mont # p256_sqr_mont(Rsqr, R);
|
||||
|
||||
ld $bi,64($ap_real)
|
||||
ld $a0,$H+0($sp)
|
||||
ld $a1,$H+8($sp)
|
||||
ld $a2,$H+16($sp)
|
||||
ld $a3,$H+24($sp)
|
||||
addi $bp,$ap_real,64
|
||||
addi $rp,$sp,$res_z
|
||||
bl __ecp_nistz256_mul_mont # p256_mul_mont(res_z, H, in1_z);
|
||||
|
||||
ld $a0,$H+0($sp)
|
||||
ld $a1,$H+8($sp)
|
||||
ld $a2,$H+16($sp)
|
||||
ld $a3,$H+24($sp)
|
||||
addi $rp,$sp,$Hsqr
|
||||
bl __ecp_nistz256_sqr_mont # p256_sqr_mont(Hsqr, H);
|
||||
|
||||
ld $bi,64($bp_real)
|
||||
ld $a0,$res_z+0($sp)
|
||||
ld $a1,$res_z+8($sp)
|
||||
ld $a2,$res_z+16($sp)
|
||||
ld $a3,$res_z+24($sp)
|
||||
addi $bp,$bp_real,64
|
||||
addi $rp,$sp,$res_z
|
||||
bl __ecp_nistz256_mul_mont # p256_mul_mont(res_z, res_z, in2_z);
|
||||
|
||||
ld $bi,$H($sp)
|
||||
ld $a0,$Hsqr+0($sp)
|
||||
ld $a1,$Hsqr+8($sp)
|
||||
ld $a2,$Hsqr+16($sp)
|
||||
ld $a3,$Hsqr+24($sp)
|
||||
addi $bp,$sp,$H
|
||||
addi $rp,$sp,$Hcub
|
||||
bl __ecp_nistz256_mul_mont # p256_mul_mont(Hcub, Hsqr, H);
|
||||
|
||||
ld $bi,$Hsqr($sp)
|
||||
ld $a0,$U1+0($sp)
|
||||
ld $a1,$U1+8($sp)
|
||||
ld $a2,$U1+16($sp)
|
||||
ld $a3,$U1+24($sp)
|
||||
addi $bp,$sp,$Hsqr
|
||||
addi $rp,$sp,$U2
|
||||
bl __ecp_nistz256_mul_mont # p256_mul_mont(U2, U1, Hsqr);
|
||||
|
||||
mr $t0,$acc0
|
||||
mr $t1,$acc1
|
||||
mr $t2,$acc2
|
||||
mr $t3,$acc3
|
||||
addi $rp,$sp,$Hsqr
|
||||
bl __ecp_nistz256_add # p256_mul_by_2(Hsqr, U2);
|
||||
|
||||
addi $bp,$sp,$Rsqr
|
||||
addi $rp,$sp,$res_x
|
||||
bl __ecp_nistz256_sub_morf # p256_sub(res_x, Rsqr, Hsqr);
|
||||
|
||||
addi $bp,$sp,$Hcub
|
||||
bl __ecp_nistz256_sub_from # p256_sub(res_x, res_x, Hcub);
|
||||
|
||||
addi $bp,$sp,$U2
|
||||
ld $bi,$Hcub($sp) # forward load for p256_mul_mont
|
||||
ld $a0,$S1+0($sp)
|
||||
ld $a1,$S1+8($sp)
|
||||
ld $a2,$S1+16($sp)
|
||||
ld $a3,$S1+24($sp)
|
||||
addi $rp,$sp,$res_y
|
||||
bl __ecp_nistz256_sub_morf # p256_sub(res_y, U2, res_x);
|
||||
|
||||
addi $bp,$sp,$Hcub
|
||||
addi $rp,$sp,$S2
|
||||
bl __ecp_nistz256_mul_mont # p256_mul_mont(S2, S1, Hcub);
|
||||
|
||||
ld $bi,$R($sp)
|
||||
ld $a0,$res_y+0($sp)
|
||||
ld $a1,$res_y+8($sp)
|
||||
ld $a2,$res_y+16($sp)
|
||||
ld $a3,$res_y+24($sp)
|
||||
addi $bp,$sp,$R
|
||||
addi $rp,$sp,$res_y
|
||||
bl __ecp_nistz256_mul_mont # p256_mul_mont(res_y, res_y, R);
|
||||
|
||||
addi $bp,$sp,$S2
|
||||
bl __ecp_nistz256_sub_from # p256_sub(res_y, res_y, S2);
|
||||
|
||||
ld $t0,0($bp_real) # in2
|
||||
ld $t1,8($bp_real)
|
||||
ld $t2,16($bp_real)
|
||||
ld $t3,24($bp_real)
|
||||
ld $a0,$res_x+0($sp) # res
|
||||
ld $a1,$res_x+8($sp)
|
||||
ld $a2,$res_x+16($sp)
|
||||
ld $a3,$res_x+24($sp)
|
||||
___
|
||||
for($i=0;$i<64;$i+=32) { # conditional moves
|
||||
$code.=<<___;
|
||||
ld $acc0,$i+0($ap_real) # in1
|
||||
ld $acc1,$i+8($ap_real)
|
||||
ld $acc2,$i+16($ap_real)
|
||||
ld $acc3,$i+24($ap_real)
|
||||
andc $t0,$t0,$in1infty
|
||||
andc $t1,$t1,$in1infty
|
||||
andc $t2,$t2,$in1infty
|
||||
andc $t3,$t3,$in1infty
|
||||
and $a0,$a0,$in1infty
|
||||
and $a1,$a1,$in1infty
|
||||
and $a2,$a2,$in1infty
|
||||
and $a3,$a3,$in1infty
|
||||
or $t0,$t0,$a0
|
||||
or $t1,$t1,$a1
|
||||
or $t2,$t2,$a2
|
||||
or $t3,$t3,$a3
|
||||
andc $acc0,$acc0,$in2infty
|
||||
andc $acc1,$acc1,$in2infty
|
||||
andc $acc2,$acc2,$in2infty
|
||||
andc $acc3,$acc3,$in2infty
|
||||
and $t0,$t0,$in2infty
|
||||
and $t1,$t1,$in2infty
|
||||
and $t2,$t2,$in2infty
|
||||
and $t3,$t3,$in2infty
|
||||
or $acc0,$acc0,$t0
|
||||
or $acc1,$acc1,$t1
|
||||
or $acc2,$acc2,$t2
|
||||
or $acc3,$acc3,$t3
|
||||
|
||||
ld $t0,$i+32($bp_real) # in2
|
||||
ld $t1,$i+40($bp_real)
|
||||
ld $t2,$i+48($bp_real)
|
||||
ld $t3,$i+56($bp_real)
|
||||
ld $a0,$res_x+$i+32($sp)
|
||||
ld $a1,$res_x+$i+40($sp)
|
||||
ld $a2,$res_x+$i+48($sp)
|
||||
ld $a3,$res_x+$i+56($sp)
|
||||
std $acc0,$i+0($rp_real)
|
||||
std $acc1,$i+8($rp_real)
|
||||
std $acc2,$i+16($rp_real)
|
||||
std $acc3,$i+24($rp_real)
|
||||
___
|
||||
}
|
||||
$code.=<<___;
|
||||
ld $acc0,$i+0($ap_real) # in1
|
||||
ld $acc1,$i+8($ap_real)
|
||||
ld $acc2,$i+16($ap_real)
|
||||
ld $acc3,$i+24($ap_real)
|
||||
andc $t0,$t0,$in1infty
|
||||
andc $t1,$t1,$in1infty
|
||||
andc $t2,$t2,$in1infty
|
||||
andc $t3,$t3,$in1infty
|
||||
and $a0,$a0,$in1infty
|
||||
and $a1,$a1,$in1infty
|
||||
and $a2,$a2,$in1infty
|
||||
and $a3,$a3,$in1infty
|
||||
or $t0,$t0,$a0
|
||||
or $t1,$t1,$a1
|
||||
or $t2,$t2,$a2
|
||||
or $t3,$t3,$a3
|
||||
andc $acc0,$acc0,$in2infty
|
||||
andc $acc1,$acc1,$in2infty
|
||||
andc $acc2,$acc2,$in2infty
|
||||
andc $acc3,$acc3,$in2infty
|
||||
and $t0,$t0,$in2infty
|
||||
and $t1,$t1,$in2infty
|
||||
and $t2,$t2,$in2infty
|
||||
and $t3,$t3,$in2infty
|
||||
or $acc0,$acc0,$t0
|
||||
or $acc1,$acc1,$t1
|
||||
or $acc2,$acc2,$t2
|
||||
or $acc3,$acc3,$t3
|
||||
std $acc0,$i+0($rp_real)
|
||||
std $acc1,$i+8($rp_real)
|
||||
std $acc2,$i+16($rp_real)
|
||||
std $acc3,$i+24($rp_real)
|
||||
|
||||
.Ladd_done:
|
||||
mtlr r0
|
||||
ld r16,$FRAME-8*16($sp)
|
||||
ld r17,$FRAME-8*15($sp)
|
||||
ld r18,$FRAME-8*14($sp)
|
||||
ld r19,$FRAME-8*13($sp)
|
||||
ld r20,$FRAME-8*12($sp)
|
||||
ld r21,$FRAME-8*11($sp)
|
||||
ld r22,$FRAME-8*10($sp)
|
||||
ld r23,$FRAME-8*9($sp)
|
||||
ld r24,$FRAME-8*8($sp)
|
||||
ld r25,$FRAME-8*7($sp)
|
||||
ld r26,$FRAME-8*6($sp)
|
||||
ld r27,$FRAME-8*5($sp)
|
||||
ld r28,$FRAME-8*4($sp)
|
||||
ld r29,$FRAME-8*3($sp)
|
||||
ld r30,$FRAME-8*2($sp)
|
||||
ld r31,$FRAME-8*1($sp)
|
||||
addi $sp,$sp,$FRAME
|
||||
blr
|
||||
.long 0
|
||||
.byte 0,12,4,0,0x80,16,3,0
|
||||
.long 0
|
||||
.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);
|
||||
if (1) {
|
||||
my $FRAME = 64 + 32*10 + 16*8;
|
||||
my ($res_x,$res_y,$res_z,
|
||||
$U2,$S2,$H,$R,$Hsqr,$Hcub,$Rsqr)=map(64+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("r$_",(16..21));
|
||||
|
||||
$code.=<<___;
|
||||
.globl ecp_nistz256_point_add_affine
|
||||
.align 5
|
||||
ecp_nistz256_point_add_affine:
|
||||
stdu $sp,-$FRAME($sp)
|
||||
mflr r0
|
||||
std r16,$FRAME-8*16($sp)
|
||||
std r17,$FRAME-8*15($sp)
|
||||
std r18,$FRAME-8*14($sp)
|
||||
std r19,$FRAME-8*13($sp)
|
||||
std r20,$FRAME-8*12($sp)
|
||||
std r21,$FRAME-8*11($sp)
|
||||
std r22,$FRAME-8*10($sp)
|
||||
std r23,$FRAME-8*9($sp)
|
||||
std r24,$FRAME-8*8($sp)
|
||||
std r25,$FRAME-8*7($sp)
|
||||
std r26,$FRAME-8*6($sp)
|
||||
std r27,$FRAME-8*5($sp)
|
||||
std r28,$FRAME-8*4($sp)
|
||||
std r29,$FRAME-8*3($sp)
|
||||
std r30,$FRAME-8*2($sp)
|
||||
std r31,$FRAME-8*1($sp)
|
||||
|
||||
li $poly1,-1
|
||||
srdi $poly1,$poly1,32 # 0x00000000ffffffff
|
||||
li $poly3,1
|
||||
orc $poly3,$poly3,$poly1 # 0xffffffff00000001
|
||||
|
||||
mr $rp_real,$rp
|
||||
mr $ap_real,$ap
|
||||
mr $bp_real,$bp
|
||||
|
||||
ld $a0,64($ap) # in1_z
|
||||
ld $a1,72($ap)
|
||||
ld $a2,80($ap)
|
||||
ld $a3,88($ap)
|
||||
or $t0,$a0,$a1
|
||||
or $t2,$a2,$a3
|
||||
or $in1infty,$t0,$t2
|
||||
neg $t0,$in1infty
|
||||
or $in1infty,$in1infty,$t0
|
||||
sradi $in1infty,$in1infty,63 # !in1infty
|
||||
|
||||
ld $acc0,0($bp) # in2_x
|
||||
ld $acc1,8($bp)
|
||||
ld $acc2,16($bp)
|
||||
ld $acc3,24($bp)
|
||||
ld $t0,32($bp) # in2_y
|
||||
ld $t1,40($bp)
|
||||
ld $t2,48($bp)
|
||||
ld $t3,56($bp)
|
||||
or $acc0,$acc0,$acc1
|
||||
or $acc2,$acc2,$acc3
|
||||
or $acc0,$acc0,$acc2
|
||||
or $t0,$t0,$t1
|
||||
or $t2,$t2,$t3
|
||||
or $t0,$t0,$t2
|
||||
or $in2infty,$acc0,$t0
|
||||
neg $t0,$in2infty
|
||||
or $in2infty,$in2infty,$t0
|
||||
sradi $in2infty,$in2infty,63 # !in2infty
|
||||
|
||||
addi $rp,$sp,$Z1sqr
|
||||
bl __ecp_nistz256_sqr_mont # p256_sqr_mont(Z1sqr, in1_z);
|
||||
|
||||
mr $a0,$acc0
|
||||
mr $a1,$acc1
|
||||
mr $a2,$acc2
|
||||
mr $a3,$acc3
|
||||
ld $bi,0($bp_real)
|
||||
addi $bp,$bp_real,0
|
||||
addi $rp,$sp,$U2
|
||||
bl __ecp_nistz256_mul_mont # p256_mul_mont(U2, Z1sqr, in2_x);
|
||||
|
||||
addi $bp,$ap_real,0
|
||||
ld $bi,64($ap_real) # forward load for p256_mul_mont
|
||||
ld $a0,$Z1sqr+0($sp)
|
||||
ld $a1,$Z1sqr+8($sp)
|
||||
ld $a2,$Z1sqr+16($sp)
|
||||
ld $a3,$Z1sqr+24($sp)
|
||||
addi $rp,$sp,$H
|
||||
bl __ecp_nistz256_sub_from # p256_sub(H, U2, in1_x);
|
||||
|
||||
addi $bp,$ap_real,64
|
||||
addi $rp,$sp,$S2
|
||||
bl __ecp_nistz256_mul_mont # p256_mul_mont(S2, Z1sqr, in1_z);
|
||||
|
||||
ld $bi,64($ap_real)
|
||||
ld $a0,$H+0($sp)
|
||||
ld $a1,$H+8($sp)
|
||||
ld $a2,$H+16($sp)
|
||||
ld $a3,$H+24($sp)
|
||||
addi $bp,$ap_real,64
|
||||
addi $rp,$sp,$res_z
|
||||
bl __ecp_nistz256_mul_mont # p256_mul_mont(res_z, H, in1_z);
|
||||
|
||||
ld $bi,32($bp_real)
|
||||
ld $a0,$S2+0($sp)
|
||||
ld $a1,$S2+8($sp)
|
||||
ld $a2,$S2+16($sp)
|
||||
ld $a3,$S2+24($sp)
|
||||
addi $bp,$bp_real,32
|
||||
addi $rp,$sp,$S2
|
||||
bl __ecp_nistz256_mul_mont # p256_mul_mont(S2, S2, in2_y);
|
||||
|
||||
addi $bp,$ap_real,32
|
||||
ld $a0,$H+0($sp) # forward load for p256_sqr_mont
|
||||
ld $a1,$H+8($sp)
|
||||
ld $a2,$H+16($sp)
|
||||
ld $a3,$H+24($sp)
|
||||
addi $rp,$sp,$R
|
||||
bl __ecp_nistz256_sub_from # p256_sub(R, S2, in1_y);
|
||||
|
||||
addi $rp,$sp,$Hsqr
|
||||
bl __ecp_nistz256_sqr_mont # p256_sqr_mont(Hsqr, H);
|
||||
|
||||
ld $a0,$R+0($sp)
|
||||
ld $a1,$R+8($sp)
|
||||
ld $a2,$R+16($sp)
|
||||
ld $a3,$R+24($sp)
|
||||
addi $rp,$sp,$Rsqr
|
||||
bl __ecp_nistz256_sqr_mont # p256_sqr_mont(Rsqr, R);
|
||||
|
||||
ld $bi,$H($sp)
|
||||
ld $a0,$Hsqr+0($sp)
|
||||
ld $a1,$Hsqr+8($sp)
|
||||
ld $a2,$Hsqr+16($sp)
|
||||
ld $a3,$Hsqr+24($sp)
|
||||
addi $bp,$sp,$H
|
||||
addi $rp,$sp,$Hcub
|
||||
bl __ecp_nistz256_mul_mont # p256_mul_mont(Hcub, Hsqr, H);
|
||||
|
||||
ld $bi,0($ap_real)
|
||||
ld $a0,$Hsqr+0($sp)
|
||||
ld $a1,$Hsqr+8($sp)
|
||||
ld $a2,$Hsqr+16($sp)
|
||||
ld $a3,$Hsqr+24($sp)
|
||||
addi $bp,$ap_real,0
|
||||
addi $rp,$sp,$U2
|
||||
bl __ecp_nistz256_mul_mont # p256_mul_mont(U2, in1_x, Hsqr);
|
||||
|
||||
mr $t0,$acc0
|
||||
mr $t1,$acc1
|
||||
mr $t2,$acc2
|
||||
mr $t3,$acc3
|
||||
addi $rp,$sp,$Hsqr
|
||||
bl __ecp_nistz256_add # p256_mul_by_2(Hsqr, U2);
|
||||
|
||||
addi $bp,$sp,$Rsqr
|
||||
addi $rp,$sp,$res_x
|
||||
bl __ecp_nistz256_sub_morf # p256_sub(res_x, Rsqr, Hsqr);
|
||||
|
||||
addi $bp,$sp,$Hcub
|
||||
bl __ecp_nistz256_sub_from # p256_sub(res_x, res_x, Hcub);
|
||||
|
||||
addi $bp,$sp,$U2
|
||||
ld $bi,32($ap_real) # forward load for p256_mul_mont
|
||||
ld $a0,$Hcub+0($sp)
|
||||
ld $a1,$Hcub+8($sp)
|
||||
ld $a2,$Hcub+16($sp)
|
||||
ld $a3,$Hcub+24($sp)
|
||||
addi $rp,$sp,$res_y
|
||||
bl __ecp_nistz256_sub_morf # p256_sub(res_y, U2, res_x);
|
||||
|
||||
addi $bp,$ap_real,32
|
||||
addi $rp,$sp,$S2
|
||||
bl __ecp_nistz256_mul_mont # p256_mul_mont(S2, in1_y, Hcub);
|
||||
|
||||
ld $bi,$R($sp)
|
||||
ld $a0,$res_y+0($sp)
|
||||
ld $a1,$res_y+8($sp)
|
||||
ld $a2,$res_y+16($sp)
|
||||
ld $a3,$res_y+24($sp)
|
||||
addi $bp,$sp,$R
|
||||
addi $rp,$sp,$res_y
|
||||
bl __ecp_nistz256_mul_mont # p256_mul_mont(res_y, res_y, R);
|
||||
|
||||
addi $bp,$sp,$S2
|
||||
bl __ecp_nistz256_sub_from # p256_sub(res_y, res_y, S2);
|
||||
|
||||
ld $t0,0($bp_real) # in2
|
||||
ld $t1,8($bp_real)
|
||||
ld $t2,16($bp_real)
|
||||
ld $t3,24($bp_real)
|
||||
ld $a0,$res_x+0($sp) # res
|
||||
ld $a1,$res_x+8($sp)
|
||||
ld $a2,$res_x+16($sp)
|
||||
ld $a3,$res_x+24($sp)
|
||||
___
|
||||
for($i=0;$i<64;$i+=32) { # conditional moves
|
||||
$code.=<<___;
|
||||
ld $acc0,$i+0($ap_real) # in1
|
||||
ld $acc1,$i+8($ap_real)
|
||||
ld $acc2,$i+16($ap_real)
|
||||
ld $acc3,$i+24($ap_real)
|
||||
andc $t0,$t0,$in1infty
|
||||
andc $t1,$t1,$in1infty
|
||||
andc $t2,$t2,$in1infty
|
||||
andc $t3,$t3,$in1infty
|
||||
and $a0,$a0,$in1infty
|
||||
and $a1,$a1,$in1infty
|
||||
and $a2,$a2,$in1infty
|
||||
and $a3,$a3,$in1infty
|
||||
or $t0,$t0,$a0
|
||||
or $t1,$t1,$a1
|
||||
or $t2,$t2,$a2
|
||||
or $t3,$t3,$a3
|
||||
andc $acc0,$acc0,$in2infty
|
||||
andc $acc1,$acc1,$in2infty
|
||||
andc $acc2,$acc2,$in2infty
|
||||
andc $acc3,$acc3,$in2infty
|
||||
and $t0,$t0,$in2infty
|
||||
and $t1,$t1,$in2infty
|
||||
and $t2,$t2,$in2infty
|
||||
and $t3,$t3,$in2infty
|
||||
or $acc0,$acc0,$t0
|
||||
or $acc1,$acc1,$t1
|
||||
or $acc2,$acc2,$t2
|
||||
or $acc3,$acc3,$t3
|
||||
___
|
||||
$code.=<<___ if ($i==0);
|
||||
ld $t0,32($bp_real) # in2
|
||||
ld $t1,40($bp_real)
|
||||
ld $t2,48($bp_real)
|
||||
ld $t3,56($bp_real)
|
||||
___
|
||||
$code.=<<___ if ($i==32);
|
||||
li $t0,1 # Lone_mont
|
||||
not $t1,$poly1
|
||||
li $t2,-1
|
||||
not $t3,$poly3
|
||||
___
|
||||
$code.=<<___;
|
||||
ld $a0,$res_x+$i+32($sp)
|
||||
ld $a1,$res_x+$i+40($sp)
|
||||
ld $a2,$res_x+$i+48($sp)
|
||||
ld $a3,$res_x+$i+56($sp)
|
||||
std $acc0,$i+0($rp_real)
|
||||
std $acc1,$i+8($rp_real)
|
||||
std $acc2,$i+16($rp_real)
|
||||
std $acc3,$i+24($rp_real)
|
||||
___
|
||||
}
|
||||
$code.=<<___;
|
||||
ld $acc0,$i+0($ap_real) # in1
|
||||
ld $acc1,$i+8($ap_real)
|
||||
ld $acc2,$i+16($ap_real)
|
||||
ld $acc3,$i+24($ap_real)
|
||||
andc $t0,$t0,$in1infty
|
||||
andc $t1,$t1,$in1infty
|
||||
andc $t2,$t2,$in1infty
|
||||
andc $t3,$t3,$in1infty
|
||||
and $a0,$a0,$in1infty
|
||||
and $a1,$a1,$in1infty
|
||||
and $a2,$a2,$in1infty
|
||||
and $a3,$a3,$in1infty
|
||||
or $t0,$t0,$a0
|
||||
or $t1,$t1,$a1
|
||||
or $t2,$t2,$a2
|
||||
or $t3,$t3,$a3
|
||||
andc $acc0,$acc0,$in2infty
|
||||
andc $acc1,$acc1,$in2infty
|
||||
andc $acc2,$acc2,$in2infty
|
||||
andc $acc3,$acc3,$in2infty
|
||||
and $t0,$t0,$in2infty
|
||||
and $t1,$t1,$in2infty
|
||||
and $t2,$t2,$in2infty
|
||||
and $t3,$t3,$in2infty
|
||||
or $acc0,$acc0,$t0
|
||||
or $acc1,$acc1,$t1
|
||||
or $acc2,$acc2,$t2
|
||||
or $acc3,$acc3,$t3
|
||||
std $acc0,$i+0($rp_real)
|
||||
std $acc1,$i+8($rp_real)
|
||||
std $acc2,$i+16($rp_real)
|
||||
std $acc3,$i+24($rp_real)
|
||||
|
||||
mtlr r0
|
||||
ld r16,$FRAME-8*16($sp)
|
||||
ld r17,$FRAME-8*15($sp)
|
||||
ld r18,$FRAME-8*14($sp)
|
||||
ld r19,$FRAME-8*13($sp)
|
||||
ld r20,$FRAME-8*12($sp)
|
||||
ld r21,$FRAME-8*11($sp)
|
||||
ld r22,$FRAME-8*10($sp)
|
||||
ld r23,$FRAME-8*9($sp)
|
||||
ld r24,$FRAME-8*8($sp)
|
||||
ld r25,$FRAME-8*7($sp)
|
||||
ld r26,$FRAME-8*6($sp)
|
||||
ld r27,$FRAME-8*5($sp)
|
||||
ld r28,$FRAME-8*4($sp)
|
||||
ld r29,$FRAME-8*3($sp)
|
||||
ld r30,$FRAME-8*2($sp)
|
||||
ld r31,$FRAME-8*1($sp)
|
||||
addi $sp,$sp,$FRAME
|
||||
blr
|
||||
.long 0
|
||||
.byte 0,12,4,0,0x80,16,3,0
|
||||
.long 0
|
||||
.size ecp_nistz256_point_add_affine,.-ecp_nistz256_point_add_affine
|
||||
___
|
||||
}
|
||||
if (1) {
|
||||
my ($ordk,$ord0,$ord1,$t4) = map("r$_",(18..21));
|
||||
my ($ord2,$ord3,$zr) = ($poly1,$poly3,"r0");
|
||||
|
||||
$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
|
||||
.align 5
|
||||
ecp_nistz256_ord_mul_mont:
|
||||
stdu $sp,-160($sp)
|
||||
std r18,48($sp)
|
||||
std r19,56($sp)
|
||||
std r20,64($sp)
|
||||
std r21,72($sp)
|
||||
std r22,80($sp)
|
||||
std r23,88($sp)
|
||||
std r24,96($sp)
|
||||
std r25,104($sp)
|
||||
std r26,112($sp)
|
||||
std r27,120($sp)
|
||||
std r28,128($sp)
|
||||
std r29,136($sp)
|
||||
std r30,144($sp)
|
||||
std r31,152($sp)
|
||||
|
||||
ld $a0,0($ap)
|
||||
ld $bi,0($bp)
|
||||
ld $a1,8($ap)
|
||||
ld $a2,16($ap)
|
||||
ld $a3,24($ap)
|
||||
|
||||
lis $ordk,0xccd1
|
||||
lis $ord0,0xf3b9
|
||||
lis $ord1,0xbce6
|
||||
ori $ordk,$ordk,0xc8aa
|
||||
ori $ord0,$ord0,0xcac2
|
||||
ori $ord1,$ord1,0xfaad
|
||||
sldi $ordk,$ordk,32
|
||||
sldi $ord0,$ord0,32
|
||||
sldi $ord1,$ord1,32
|
||||
oris $ordk,$ordk,0xee00
|
||||
oris $ord0,$ord0,0xfc63
|
||||
oris $ord1,$ord1,0xa717
|
||||
ori $ordk,$ordk,0xbc4f # 0xccd1c8aaee00bc4f
|
||||
ori $ord0,$ord0,0x2551 # 0xf3b9cac2fc632551
|
||||
ori $ord1,$ord1,0x9e84 # 0xbce6faada7179e84
|
||||
li $ord2,-1 # 0xffffffffffffffff
|
||||
sldi $ord3,$ord2,32 # 0xffffffff00000000
|
||||
li $zr,0
|
||||
|
||||
mulld $acc0,$a0,$bi # a[0]*b[0]
|
||||
mulhdu $t0,$a0,$bi
|
||||
|
||||
mulld $acc1,$a1,$bi # a[1]*b[0]
|
||||
mulhdu $t1,$a1,$bi
|
||||
|
||||
mulld $acc2,$a2,$bi # a[2]*b[0]
|
||||
mulhdu $t2,$a2,$bi
|
||||
|
||||
mulld $acc3,$a3,$bi # a[3]*b[0]
|
||||
mulhdu $acc4,$a3,$bi
|
||||
|
||||
mulld $t4,$acc0,$ordk
|
||||
|
||||
addc $acc1,$acc1,$t0 # accumulate high parts of multiplication
|
||||
adde $acc2,$acc2,$t1
|
||||
adde $acc3,$acc3,$t2
|
||||
addze $acc4,$acc4
|
||||
li $acc5,0
|
||||
___
|
||||
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.=<<___;
|
||||
ld $bi,8*$i($bp) # b[i]
|
||||
|
||||
sldi $t0,$t4,32
|
||||
subfc $acc2,$t4,$acc2
|
||||
srdi $t1,$t4,32
|
||||
subfe $acc3,$t0,$acc3
|
||||
subfe $acc4,$t1,$acc4
|
||||
subfe $acc5,$zr,$acc5
|
||||
|
||||
addic $t0,$acc0,-1 # discarded
|
||||
mulhdu $t1,$ord0,$t4
|
||||
mulld $t2,$ord1,$t4
|
||||
mulhdu $t3,$ord1,$t4
|
||||
|
||||
adde $t2,$t2,$t1
|
||||
mulld $t0,$a0,$bi
|
||||
addze $t3,$t3
|
||||
mulld $t1,$a1,$bi
|
||||
|
||||
addc $acc0,$acc1,$t2
|
||||
mulld $t2,$a2,$bi
|
||||
adde $acc1,$acc2,$t3
|
||||
mulld $t3,$a3,$bi
|
||||
adde $acc2,$acc3,$t4
|
||||
adde $acc3,$acc4,$t4
|
||||
addze $acc4,$acc5
|
||||
|
||||
addc $acc0,$acc0,$t0 # accumulate low parts
|
||||
mulhdu $t0,$a0,$bi
|
||||
adde $acc1,$acc1,$t1
|
||||
mulhdu $t1,$a1,$bi
|
||||
adde $acc2,$acc2,$t2
|
||||
mulhdu $t2,$a2,$bi
|
||||
adde $acc3,$acc3,$t3
|
||||
mulhdu $t3,$a3,$bi
|
||||
addze $acc4,$acc4
|
||||
mulld $t4,$acc0,$ordk
|
||||
addc $acc1,$acc1,$t0 # accumulate high parts
|
||||
adde $acc2,$acc2,$t1
|
||||
adde $acc3,$acc3,$t2
|
||||
adde $acc4,$acc4,$t3
|
||||
addze $acc5,$zr
|
||||
___
|
||||
}
|
||||
$code.=<<___;
|
||||
sldi $t0,$t4,32 # last reduction
|
||||
subfc $acc2,$t4,$acc2
|
||||
srdi $t1,$t4,32
|
||||
subfe $acc3,$t0,$acc3
|
||||
subfe $acc4,$t1,$acc4
|
||||
subfe $acc5,$zr,$acc5
|
||||
|
||||
addic $t0,$acc0,-1 # discarded
|
||||
mulhdu $t1,$ord0,$t4
|
||||
mulld $t2,$ord1,$t4
|
||||
mulhdu $t3,$ord1,$t4
|
||||
|
||||
adde $t2,$t2,$t1
|
||||
addze $t3,$t3
|
||||
|
||||
addc $acc0,$acc1,$t2
|
||||
adde $acc1,$acc2,$t3
|
||||
adde $acc2,$acc3,$t4
|
||||
adde $acc3,$acc4,$t4
|
||||
addze $acc4,$acc5
|
||||
|
||||
subfc $acc0,$ord0,$acc0 # ret -= modulus
|
||||
subfe $acc1,$ord1,$acc1
|
||||
subfe $acc2,$ord2,$acc2
|
||||
subfe $acc3,$ord3,$acc3
|
||||
subfe $acc4,$zr,$acc4
|
||||
|
||||
and $t0,$ord0,$acc4
|
||||
and $t1,$ord1,$acc4
|
||||
addc $acc0,$acc0,$t0 # ret += modulus if borrow
|
||||
and $t3,$ord3,$acc4
|
||||
adde $acc1,$acc1,$t1
|
||||
adde $acc2,$acc2,$acc4
|
||||
adde $acc3,$acc3,$t3
|
||||
|
||||
std $acc0,0($rp)
|
||||
std $acc1,8($rp)
|
||||
std $acc2,16($rp)
|
||||
std $acc3,24($rp)
|
||||
|
||||
ld r18,48($sp)
|
||||
ld r19,56($sp)
|
||||
ld r20,64($sp)
|
||||
ld r21,72($sp)
|
||||
ld r22,80($sp)
|
||||
ld r23,88($sp)
|
||||
ld r24,96($sp)
|
||||
ld r25,104($sp)
|
||||
ld r26,112($sp)
|
||||
ld r27,120($sp)
|
||||
ld r28,128($sp)
|
||||
ld r29,136($sp)
|
||||
ld r30,144($sp)
|
||||
ld r31,152($sp)
|
||||
addi $sp,$sp,160
|
||||
blr
|
||||
.long 0
|
||||
.byte 0,12,4,0,0x80,14,3,0
|
||||
.long 0
|
||||
.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],
|
||||
# int rep);
|
||||
.globl ecp_nistz256_ord_sqr_mont
|
||||
.align 5
|
||||
ecp_nistz256_ord_sqr_mont:
|
||||
stdu $sp,-160($sp)
|
||||
std r18,48($sp)
|
||||
std r19,56($sp)
|
||||
std r20,64($sp)
|
||||
std r21,72($sp)
|
||||
std r22,80($sp)
|
||||
std r23,88($sp)
|
||||
std r24,96($sp)
|
||||
std r25,104($sp)
|
||||
std r26,112($sp)
|
||||
std r27,120($sp)
|
||||
std r28,128($sp)
|
||||
std r29,136($sp)
|
||||
std r30,144($sp)
|
||||
std r31,152($sp)
|
||||
|
||||
mtctr $bp
|
||||
|
||||
ld $a0,0($ap)
|
||||
ld $a1,8($ap)
|
||||
ld $a2,16($ap)
|
||||
ld $a3,24($ap)
|
||||
|
||||
lis $ordk,0xccd1
|
||||
lis $ord0,0xf3b9
|
||||
lis $ord1,0xbce6
|
||||
ori $ordk,$ordk,0xc8aa
|
||||
ori $ord0,$ord0,0xcac2
|
||||
ori $ord1,$ord1,0xfaad
|
||||
sldi $ordk,$ordk,32
|
||||
sldi $ord0,$ord0,32
|
||||
sldi $ord1,$ord1,32
|
||||
oris $ordk,$ordk,0xee00
|
||||
oris $ord0,$ord0,0xfc63
|
||||
oris $ord1,$ord1,0xa717
|
||||
ori $ordk,$ordk,0xbc4f # 0xccd1c8aaee00bc4f
|
||||
ori $ord0,$ord0,0x2551 # 0xf3b9cac2fc632551
|
||||
ori $ord1,$ord1,0x9e84 # 0xbce6faada7179e84
|
||||
li $ord2,-1 # 0xffffffffffffffff
|
||||
sldi $ord3,$ord2,32 # 0xffffffff00000000
|
||||
li $zr,0
|
||||
b .Loop_ord_sqr
|
||||
|
||||
.align 5
|
||||
.Loop_ord_sqr:
|
||||
################################################################
|
||||
# | | | | | |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.
|
||||
|
||||
mulld $acc1,$a1,$a0 # a[1]*a[0]
|
||||
mulhdu $t1,$a1,$a0
|
||||
mulld $acc2,$a2,$a0 # a[2]*a[0]
|
||||
mulhdu $t2,$a2,$a0
|
||||
mulld $acc3,$a3,$a0 # a[3]*a[0]
|
||||
mulhdu $acc4,$a3,$a0
|
||||
|
||||
addc $acc2,$acc2,$t1 # accumulate high parts of multiplication
|
||||
mulld $t0,$a2,$a1 # a[2]*a[1]
|
||||
mulhdu $t1,$a2,$a1
|
||||
adde $acc3,$acc3,$t2
|
||||
mulld $t2,$a3,$a1 # a[3]*a[1]
|
||||
mulhdu $t3,$a3,$a1
|
||||
addze $acc4,$acc4 # can't overflow
|
||||
|
||||
mulld $acc5,$a3,$a2 # a[3]*a[2]
|
||||
mulhdu $acc6,$a3,$a2
|
||||
|
||||
addc $t1,$t1,$t2 # accumulate high parts of multiplication
|
||||
mulld $acc0,$a0,$a0 # a[0]*a[0]
|
||||
addze $t2,$t3 # can't overflow
|
||||
|
||||
addc $acc3,$acc3,$t0 # accumulate low parts of multiplication
|
||||
mulhdu $a0,$a0,$a0
|
||||
adde $acc4,$acc4,$t1
|
||||
mulld $t1,$a1,$a1 # a[1]*a[1]
|
||||
adde $acc5,$acc5,$t2
|
||||
mulhdu $a1,$a1,$a1
|
||||
addze $acc6,$acc6 # can't overflow
|
||||
|
||||
addc $acc1,$acc1,$acc1 # acc[1-6]*=2
|
||||
mulld $t2,$a2,$a2 # a[2]*a[2]
|
||||
adde $acc2,$acc2,$acc2
|
||||
mulhdu $a2,$a2,$a2
|
||||
adde $acc3,$acc3,$acc3
|
||||
mulld $t3,$a3,$a3 # a[3]*a[3]
|
||||
adde $acc4,$acc4,$acc4
|
||||
mulhdu $a3,$a3,$a3
|
||||
adde $acc5,$acc5,$acc5
|
||||
adde $acc6,$acc6,$acc6
|
||||
addze $acc7,$zr
|
||||
|
||||
addc $acc1,$acc1,$a0 # +a[i]*a[i]
|
||||
mulld $t4,$acc0,$ordk
|
||||
adde $acc2,$acc2,$t1
|
||||
adde $acc3,$acc3,$a1
|
||||
adde $acc4,$acc4,$t2
|
||||
adde $acc5,$acc5,$a2
|
||||
adde $acc6,$acc6,$t3
|
||||
adde $acc7,$acc7,$a3
|
||||
___
|
||||
for($i=0; $i<4; $i++) { # reductions
|
||||
$code.=<<___;
|
||||
addic $t0,$acc0,-1 # discarded
|
||||
mulhdu $t1,$ord0,$t4
|
||||
mulld $t2,$ord1,$t4
|
||||
mulhdu $t3,$ord1,$t4
|
||||
|
||||
adde $t2,$t2,$t1
|
||||
addze $t3,$t3
|
||||
|
||||
addc $acc0,$acc1,$t2
|
||||
adde $acc1,$acc2,$t3
|
||||
adde $acc2,$acc3,$t4
|
||||
adde $acc3,$zr,$t4 # can't overflow
|
||||
___
|
||||
$code.=<<___ if ($i<3);
|
||||
mulld $t3,$acc0,$ordk
|
||||
___
|
||||
$code.=<<___;
|
||||
sldi $t0,$t4,32
|
||||
subfc $acc1,$t4,$acc1
|
||||
srdi $t1,$t4,32
|
||||
subfe $acc2,$t0,$acc2
|
||||
subfe $acc3,$t1,$acc3 # can't borrow
|
||||
___
|
||||
($t3,$t4) = ($t4,$t3);
|
||||
}
|
||||
$code.=<<___;
|
||||
addc $acc0,$acc0,$acc4 # accumulate upper half
|
||||
adde $acc1,$acc1,$acc5
|
||||
adde $acc2,$acc2,$acc6
|
||||
adde $acc3,$acc3,$acc7
|
||||
addze $acc4,$zr
|
||||
|
||||
subfc $acc0,$ord0,$acc0 # ret -= modulus
|
||||
subfe $acc1,$ord1,$acc1
|
||||
subfe $acc2,$ord2,$acc2
|
||||
subfe $acc3,$ord3,$acc3
|
||||
subfe $acc4,$zr,$acc4
|
||||
|
||||
and $t0,$ord0,$acc4
|
||||
and $t1,$ord1,$acc4
|
||||
addc $a0,$acc0,$t0 # ret += modulus if borrow
|
||||
and $t3,$ord3,$acc4
|
||||
adde $a1,$acc1,$t1
|
||||
adde $a2,$acc2,$acc4
|
||||
adde $a3,$acc3,$t3
|
||||
|
||||
bdnz .Loop_ord_sqr
|
||||
|
||||
std $a0,0($rp)
|
||||
std $a1,8($rp)
|
||||
std $a2,16($rp)
|
||||
std $a3,24($rp)
|
||||
|
||||
ld r18,48($sp)
|
||||
ld r19,56($sp)
|
||||
ld r20,64($sp)
|
||||
ld r21,72($sp)
|
||||
ld r22,80($sp)
|
||||
ld r23,88($sp)
|
||||
ld r24,96($sp)
|
||||
ld r25,104($sp)
|
||||
ld r26,112($sp)
|
||||
ld r27,120($sp)
|
||||
ld r28,128($sp)
|
||||
ld r29,136($sp)
|
||||
ld r30,144($sp)
|
||||
ld r31,152($sp)
|
||||
addi $sp,$sp,160
|
||||
blr
|
||||
.long 0
|
||||
.byte 0,12,4,0,0x80,14,3,0
|
||||
.long 0
|
||||
.size ecp_nistz256_ord_sqr_mont,.-ecp_nistz256_ord_sqr_mont
|
||||
___
|
||||
} }
|
||||
|
||||
########################################################################
|
||||
# scatter-gather subroutines
|
||||
{
|
||||
my ($out,$inp,$index,$mask)=map("r$_",(3..7));
|
||||
$code.=<<___;
|
||||
########################################################################
|
||||
# void ecp_nistz256_scatter_w5(void *out, const P256_POINT *inp,
|
||||
# int index);
|
||||
.globl ecp_nistz256_scatter_w5
|
||||
.align 4
|
||||
ecp_nistz256_scatter_w5:
|
||||
slwi $index,$index,2
|
||||
add $out,$out,$index
|
||||
|
||||
ld r8, 0($inp) # X
|
||||
ld r9, 8($inp)
|
||||
ld r10,16($inp)
|
||||
ld r11,24($inp)
|
||||
|
||||
stw r8, 64*0-4($out)
|
||||
srdi r8, r8, 32
|
||||
stw r9, 64*1-4($out)
|
||||
srdi r9, r9, 32
|
||||
stw r10,64*2-4($out)
|
||||
srdi r10,r10,32
|
||||
stw r11,64*3-4($out)
|
||||
srdi r11,r11,32
|
||||
stw r8, 64*4-4($out)
|
||||
stw r9, 64*5-4($out)
|
||||
stw r10,64*6-4($out)
|
||||
stw r11,64*7-4($out)
|
||||
addi $out,$out,64*8
|
||||
|
||||
ld r8, 32($inp) # Y
|
||||
ld r9, 40($inp)
|
||||
ld r10,48($inp)
|
||||
ld r11,56($inp)
|
||||
|
||||
stw r8, 64*0-4($out)
|
||||
srdi r8, r8, 32
|
||||
stw r9, 64*1-4($out)
|
||||
srdi r9, r9, 32
|
||||
stw r10,64*2-4($out)
|
||||
srdi r10,r10,32
|
||||
stw r11,64*3-4($out)
|
||||
srdi r11,r11,32
|
||||
stw r8, 64*4-4($out)
|
||||
stw r9, 64*5-4($out)
|
||||
stw r10,64*6-4($out)
|
||||
stw r11,64*7-4($out)
|
||||
addi $out,$out,64*8
|
||||
|
||||
ld r8, 64($inp) # Z
|
||||
ld r9, 72($inp)
|
||||
ld r10,80($inp)
|
||||
ld r11,88($inp)
|
||||
|
||||
stw r8, 64*0-4($out)
|
||||
srdi r8, r8, 32
|
||||
stw r9, 64*1-4($out)
|
||||
srdi r9, r9, 32
|
||||
stw r10,64*2-4($out)
|
||||
srdi r10,r10,32
|
||||
stw r11,64*3-4($out)
|
||||
srdi r11,r11,32
|
||||
stw r8, 64*4-4($out)
|
||||
stw r9, 64*5-4($out)
|
||||
stw r10,64*6-4($out)
|
||||
stw r11,64*7-4($out)
|
||||
|
||||
blr
|
||||
.long 0
|
||||
.byte 0,12,0x14,0,0,0,3,0
|
||||
.long 0
|
||||
.size ecp_nistz256_scatter_w5,.-ecp_nistz256_scatter_w5
|
||||
|
||||
########################################################################
|
||||
# void ecp_nistz256_gather_w5(P256_POINT *out, const void *inp,
|
||||
# int index);
|
||||
.globl ecp_nistz256_gather_w5
|
||||
.align 4
|
||||
ecp_nistz256_gather_w5:
|
||||
neg r0,$index
|
||||
sradi r0,r0,63
|
||||
|
||||
add $index,$index,r0
|
||||
slwi $index,$index,2
|
||||
add $inp,$inp,$index
|
||||
|
||||
lwz r5, 64*0($inp)
|
||||
lwz r6, 64*1($inp)
|
||||
lwz r7, 64*2($inp)
|
||||
lwz r8, 64*3($inp)
|
||||
lwz r9, 64*4($inp)
|
||||
lwz r10,64*5($inp)
|
||||
lwz r11,64*6($inp)
|
||||
lwz r12,64*7($inp)
|
||||
addi $inp,$inp,64*8
|
||||
sldi r9, r9, 32
|
||||
sldi r10,r10,32
|
||||
sldi r11,r11,32
|
||||
sldi r12,r12,32
|
||||
or r5,r5,r9
|
||||
or r6,r6,r10
|
||||
or r7,r7,r11
|
||||
or r8,r8,r12
|
||||
and r5,r5,r0
|
||||
and r6,r6,r0
|
||||
and r7,r7,r0
|
||||
and r8,r8,r0
|
||||
std r5,0($out) # X
|
||||
std r6,8($out)
|
||||
std r7,16($out)
|
||||
std r8,24($out)
|
||||
|
||||
lwz r5, 64*0($inp)
|
||||
lwz r6, 64*1($inp)
|
||||
lwz r7, 64*2($inp)
|
||||
lwz r8, 64*3($inp)
|
||||
lwz r9, 64*4($inp)
|
||||
lwz r10,64*5($inp)
|
||||
lwz r11,64*6($inp)
|
||||
lwz r12,64*7($inp)
|
||||
addi $inp,$inp,64*8
|
||||
sldi r9, r9, 32
|
||||
sldi r10,r10,32
|
||||
sldi r11,r11,32
|
||||
sldi r12,r12,32
|
||||
or r5,r5,r9
|
||||
or r6,r6,r10
|
||||
or r7,r7,r11
|
||||
or r8,r8,r12
|
||||
and r5,r5,r0
|
||||
and r6,r6,r0
|
||||
and r7,r7,r0
|
||||
and r8,r8,r0
|
||||
std r5,32($out) # Y
|
||||
std r6,40($out)
|
||||
std r7,48($out)
|
||||
std r8,56($out)
|
||||
|
||||
lwz r5, 64*0($inp)
|
||||
lwz r6, 64*1($inp)
|
||||
lwz r7, 64*2($inp)
|
||||
lwz r8, 64*3($inp)
|
||||
lwz r9, 64*4($inp)
|
||||
lwz r10,64*5($inp)
|
||||
lwz r11,64*6($inp)
|
||||
lwz r12,64*7($inp)
|
||||
sldi r9, r9, 32
|
||||
sldi r10,r10,32
|
||||
sldi r11,r11,32
|
||||
sldi r12,r12,32
|
||||
or r5,r5,r9
|
||||
or r6,r6,r10
|
||||
or r7,r7,r11
|
||||
or r8,r8,r12
|
||||
and r5,r5,r0
|
||||
and r6,r6,r0
|
||||
and r7,r7,r0
|
||||
and r8,r8,r0
|
||||
std r5,64($out) # Z
|
||||
std r6,72($out)
|
||||
std r7,80($out)
|
||||
std r8,88($out)
|
||||
|
||||
blr
|
||||
.long 0
|
||||
.byte 0,12,0x14,0,0,0,3,0
|
||||
.long 0
|
||||
.size ecp_nistz256_gather_w5,.-ecp_nistz256_gather_w5
|
||||
|
||||
########################################################################
|
||||
# void ecp_nistz256_scatter_w7(void *out, const P256_POINT_AFFINE *inp,
|
||||
# int index);
|
||||
.globl ecp_nistz256_scatter_w7
|
||||
.align 4
|
||||
ecp_nistz256_scatter_w7:
|
||||
li r0,8
|
||||
mtctr r0
|
||||
add $out,$out,$index
|
||||
subi $inp,$inp,8
|
||||
|
||||
.Loop_scatter_w7:
|
||||
ldu r0,8($inp)
|
||||
stb r0,64*0-1($out)
|
||||
srdi r0,r0,8
|
||||
stb r0,64*1-1($out)
|
||||
srdi r0,r0,8
|
||||
stb r0,64*2-1($out)
|
||||
srdi r0,r0,8
|
||||
stb r0,64*3-1($out)
|
||||
srdi r0,r0,8
|
||||
stb r0,64*4-1($out)
|
||||
srdi r0,r0,8
|
||||
stb r0,64*5-1($out)
|
||||
srdi r0,r0,8
|
||||
stb r0,64*6-1($out)
|
||||
srdi r0,r0,8
|
||||
stb r0,64*7-1($out)
|
||||
addi $out,$out,64*8
|
||||
bdnz .Loop_scatter_w7
|
||||
|
||||
blr
|
||||
.long 0
|
||||
.byte 0,12,0x14,0,0,0,3,0
|
||||
.long 0
|
||||
.size ecp_nistz256_scatter_w7,.-ecp_nistz256_scatter_w7
|
||||
|
||||
########################################################################
|
||||
# void ecp_nistz256_gather_w7(P256_POINT_AFFINE *out, const void *inp,
|
||||
# int index);
|
||||
.globl ecp_nistz256_gather_w7
|
||||
.align 4
|
||||
ecp_nistz256_gather_w7:
|
||||
li r0,8
|
||||
mtctr r0
|
||||
neg r0,$index
|
||||
sradi r0,r0,63
|
||||
|
||||
add $index,$index,r0
|
||||
add $inp,$inp,$index
|
||||
subi $out,$out,8
|
||||
|
||||
.Loop_gather_w7:
|
||||
lbz r5, 64*0($inp)
|
||||
lbz r6, 64*1($inp)
|
||||
lbz r7, 64*2($inp)
|
||||
lbz r8, 64*3($inp)
|
||||
lbz r9, 64*4($inp)
|
||||
lbz r10,64*5($inp)
|
||||
lbz r11,64*6($inp)
|
||||
lbz r12,64*7($inp)
|
||||
addi $inp,$inp,64*8
|
||||
|
||||
sldi r6, r6, 8
|
||||
sldi r7, r7, 16
|
||||
sldi r8, r8, 24
|
||||
sldi r9, r9, 32
|
||||
sldi r10,r10,40
|
||||
sldi r11,r11,48
|
||||
sldi r12,r12,56
|
||||
|
||||
or r5,r5,r6
|
||||
or r7,r7,r8
|
||||
or r9,r9,r10
|
||||
or r11,r11,r12
|
||||
or r5,r5,r7
|
||||
or r9,r9,r11
|
||||
or r5,r5,r9
|
||||
and r5,r5,r0
|
||||
stdu r5,8($out)
|
||||
bdnz .Loop_gather_w7
|
||||
|
||||
blr
|
||||
.long 0
|
||||
.byte 0,12,0x14,0,0,0,3,0
|
||||
.long 0
|
||||
.size ecp_nistz256_gather_w7,.-ecp_nistz256_gather_w7
|
||||
___
|
||||
}
|
||||
|
||||
foreach (split("\n",$code)) {
|
||||
s/\`([^\`]*)\`/eval $1/ge;
|
||||
|
||||
print $_,"\n";
|
||||
}
|
||||
close STDOUT; # enforce flush
|
||||
@@ -413,7 +413,7 @@ __ecp_nistz256_add:
|
||||
! if a+b >= modulus, subtract modulus.
|
||||
!
|
||||
! But since comparison implies subtraction, we subtract
|
||||
! modulus and then add it back if subraction borrowed.
|
||||
! modulus and then add it back if subtraction borrowed.
|
||||
|
||||
subcc @acc[0],-1,@acc[0]
|
||||
subccc @acc[1],-1,@acc[1]
|
||||
@@ -1592,7 +1592,7 @@ ___
|
||||
########################################################################
|
||||
# Following subroutines are VIS3 counterparts of those above that
|
||||
# implement ones found in ecp_nistz256.c. Key difference is that they
|
||||
# use 128-bit muliplication and addition with 64-bit carry, and in order
|
||||
# use 128-bit multiplication and addition with 64-bit carry, and in order
|
||||
# to do that they perform conversion from uin32_t[8] to uint64_t[4] upon
|
||||
# entry and vice versa on return.
|
||||
#
|
||||
@@ -1874,7 +1874,7 @@ $code.=<<___ if ($i<3);
|
||||
ldx [$bp+8*($i+1)],$bi ! bp[$i+1]
|
||||
___
|
||||
$code.=<<___;
|
||||
addcc $acc1,$t0,$acc1 ! accumulate high parts of multiplication
|
||||
addcc $acc1,$t0,$acc1 ! accumulate high parts of multiplication
|
||||
sllx $acc0,32,$t0
|
||||
addxccc $acc2,$t1,$acc2
|
||||
srlx $acc0,32,$t1
|
||||
@@ -1977,7 +1977,7 @@ $code.=<<___;
|
||||
srlx $acc0,32,$t1
|
||||
addxccc $acc3,$t2,$acc2 ! +=acc[0]*0xFFFFFFFF00000001
|
||||
sub $acc0,$t0,$t2 ! acc0*0xFFFFFFFF00000001, low part
|
||||
addxc %g0,$t3,$acc3 ! cant't overflow
|
||||
addxc %g0,$t3,$acc3 ! can't overflow
|
||||
___
|
||||
}
|
||||
$code.=<<___;
|
||||
|
||||
@@ -45,7 +45,7 @@ require "x86asm.pl";
|
||||
$output=pop;
|
||||
open STDOUT,">$output";
|
||||
|
||||
&asm_init($ARGV[0],"ecp_nistz256-x86.pl",$ARGV[$#ARGV] eq "386");
|
||||
&asm_init($ARGV[0],$ARGV[$#ARGV] eq "386");
|
||||
|
||||
$sse2=0;
|
||||
for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
|
||||
@@ -443,7 +443,7 @@ for(1..37) {
|
||||
&mov (&DWP(20,"esp"),"eax");
|
||||
&mov (&DWP(24,"esp"),"eax");
|
||||
&mov (&DWP(28,"esp"),"eax");
|
||||
|
||||
|
||||
&call ("_ecp_nistz256_sub");
|
||||
|
||||
&stack_pop(8);
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
#! /usr/bin/env perl
|
||||
# Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
# Copyright 2014-2018 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)
|
||||
# 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
|
||||
|
||||
Executable
+818
@@ -0,0 +1,818 @@
|
||||
#!/usr/bin/env perl
|
||||
# Copyright 2018 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/.
|
||||
# ====================================================================
|
||||
#
|
||||
# X25519 lower-level primitives for x86_86.
|
||||
#
|
||||
# February 2018.
|
||||
#
|
||||
# This module implements radix 2^51 multiplication and squaring, and
|
||||
# radix 2^64 multiplication, squaring, addition, subtraction and final
|
||||
# reduction. Latter radix is used on ADCX/ADOX-capable processors such
|
||||
# as Broadwell. On related note one should mention that there are
|
||||
# vector implementations that provide significantly better performance
|
||||
# on some processors(*), but they are large and overly complex. Which
|
||||
# in combination with them being effectively processor-specific makes
|
||||
# the undertaking hard to justify. The goal for this implementation
|
||||
# is rather versatility and simplicity [and ultimately formal
|
||||
# verification].
|
||||
#
|
||||
# (*) For example sandy2x should provide ~30% improvement on Sandy
|
||||
# Bridge, but only nominal ~5% on Haswell [and big loss on
|
||||
# Broadwell and successors].
|
||||
#
|
||||
######################################################################
|
||||
# Improvement coefficients:
|
||||
#
|
||||
# amd64-51(*) gcc-5.x(**)
|
||||
#
|
||||
# P4 +22% +40%
|
||||
# Sandy Bridge -3% +11%
|
||||
# Haswell -1% +13%
|
||||
# Broadwell(***) +26% +30%
|
||||
# Skylake(***) +30% +47%
|
||||
# Silvermont +20% +26%
|
||||
# Goldmont +40% +50%
|
||||
# Bulldozer +20% +9%
|
||||
# Ryzen(***) +35% +32%
|
||||
# VIA +170% +120%
|
||||
#
|
||||
# (*) amd64-51 is popular assembly implementation with 2^51 radix,
|
||||
# only multiplication and squaring subroutines were linked
|
||||
# for comparison, but not complete ladder step; gain on most
|
||||
# processors is because this module refrains from shld, and
|
||||
# minor regression on others is because this does result in
|
||||
# higher instruction count;
|
||||
# (**) compiler is free to inline functions, in assembly one would
|
||||
# need to implement ladder step to do that, and it will improve
|
||||
# performance by several percent;
|
||||
# (***) ADCX/ADOX result for 2^64 radix, there is no corresponding
|
||||
# C implementation, so that comparison is always against
|
||||
# 2^51 radix;
|
||||
|
||||
$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;
|
||||
|
||||
if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
|
||||
=~ /GNU assembler version ([2-9]\.[0-9]+)/) {
|
||||
$addx = ($1>=2.23);
|
||||
}
|
||||
|
||||
if (!$addx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
|
||||
`nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
|
||||
$addx = ($1>=2.10);
|
||||
}
|
||||
|
||||
if (!$addx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
|
||||
`ml64 2>&1` =~ /Version ([0-9]+)\./) {
|
||||
$addx = ($1>=12);
|
||||
}
|
||||
|
||||
if (!$addx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([3-9])\.([0-9]+)/) {
|
||||
my $ver = $2 + $3/100.0; # 3.1->3.01, 3.10->3.10
|
||||
$addx = ($ver>=3.03);
|
||||
}
|
||||
|
||||
$code.=<<___;
|
||||
.text
|
||||
|
||||
.globl x25519_fe51_mul
|
||||
.type x25519_fe51_mul,\@function,3
|
||||
.align 32
|
||||
x25519_fe51_mul:
|
||||
push %rbp
|
||||
push %rbx
|
||||
push %r12
|
||||
push %r13
|
||||
push %r14
|
||||
push %r15
|
||||
lea -8*5(%rsp),%rsp
|
||||
|
||||
mov 8*0(%rsi),%rax # f[0]
|
||||
mov 8*0(%rdx),%r11 # load g[0-4]
|
||||
mov 8*1(%rdx),%r12
|
||||
mov 8*2(%rdx),%r13
|
||||
mov 8*3(%rdx),%rbp
|
||||
mov 8*4(%rdx),%r14
|
||||
|
||||
mov %rdi,8*4(%rsp) # offload 1st argument
|
||||
mov %rax,%rdi
|
||||
mulq %r11 # f[0]*g[0]
|
||||
mov %r11,8*0(%rsp) # offload g[0]
|
||||
mov %rax,%rbx # %rbx:%rcx = h0
|
||||
mov %rdi,%rax
|
||||
mov %rdx,%rcx
|
||||
mulq %r12 # f[0]*g[1]
|
||||
mov %r12,8*1(%rsp) # offload g[1]
|
||||
mov %rax,%r8 # %r8:%r9 = h1
|
||||
mov %rdi,%rax
|
||||
lea (%r14,%r14,8),%r15
|
||||
mov %rdx,%r9
|
||||
mulq %r13 # f[0]*g[2]
|
||||
mov %r13,8*2(%rsp) # offload g[2]
|
||||
mov %rax,%r10 # %r10:%r11 = h2
|
||||
mov %rdi,%rax
|
||||
lea (%r14,%r15,2),%rdi # g[4]*19
|
||||
mov %rdx,%r11
|
||||
mulq %rbp # f[0]*g[3]
|
||||
mov %rax,%r12 # %r12:%r13 = h3
|
||||
mov 8*0(%rsi),%rax # f[0]
|
||||
mov %rdx,%r13
|
||||
mulq %r14 # f[0]*g[4]
|
||||
mov %rax,%r14 # %r14:%r15 = h4
|
||||
mov 8*1(%rsi),%rax # f[1]
|
||||
mov %rdx,%r15
|
||||
|
||||
mulq %rdi # f[1]*g[4]*19
|
||||
add %rax,%rbx
|
||||
mov 8*2(%rsi),%rax # f[2]
|
||||
adc %rdx,%rcx
|
||||
mulq %rdi # f[2]*g[4]*19
|
||||
add %rax,%r8
|
||||
mov 8*3(%rsi),%rax # f[3]
|
||||
adc %rdx,%r9
|
||||
mulq %rdi # f[3]*g[4]*19
|
||||
add %rax,%r10
|
||||
mov 8*4(%rsi),%rax # f[4]
|
||||
adc %rdx,%r11
|
||||
mulq %rdi # f[4]*g[4]*19
|
||||
imulq \$19,%rbp,%rdi # g[3]*19
|
||||
add %rax,%r12
|
||||
mov 8*1(%rsi),%rax # f[1]
|
||||
adc %rdx,%r13
|
||||
mulq %rbp # f[1]*g[3]
|
||||
mov 8*2(%rsp),%rbp # g[2]
|
||||
add %rax,%r14
|
||||
mov 8*2(%rsi),%rax # f[2]
|
||||
adc %rdx,%r15
|
||||
|
||||
mulq %rdi # f[2]*g[3]*19
|
||||
add %rax,%rbx
|
||||
mov 8*3(%rsi),%rax # f[3]
|
||||
adc %rdx,%rcx
|
||||
mulq %rdi # f[3]*g[3]*19
|
||||
add %rax,%r8
|
||||
mov 8*4(%rsi),%rax # f[4]
|
||||
adc %rdx,%r9
|
||||
mulq %rdi # f[4]*g[3]*19
|
||||
imulq \$19,%rbp,%rdi # g[2]*19
|
||||
add %rax,%r10
|
||||
mov 8*1(%rsi),%rax # f[1]
|
||||
adc %rdx,%r11
|
||||
mulq %rbp # f[1]*g[2]
|
||||
add %rax,%r12
|
||||
mov 8*2(%rsi),%rax # f[2]
|
||||
adc %rdx,%r13
|
||||
mulq %rbp # f[2]*g[2]
|
||||
mov 8*1(%rsp),%rbp # g[1]
|
||||
add %rax,%r14
|
||||
mov 8*3(%rsi),%rax # f[3]
|
||||
adc %rdx,%r15
|
||||
|
||||
mulq %rdi # f[3]*g[2]*19
|
||||
add %rax,%rbx
|
||||
mov 8*4(%rsi),%rax # f[3]
|
||||
adc %rdx,%rcx
|
||||
mulq %rdi # f[4]*g[2]*19
|
||||
add %rax,%r8
|
||||
mov 8*1(%rsi),%rax # f[1]
|
||||
adc %rdx,%r9
|
||||
mulq %rbp # f[1]*g[1]
|
||||
imulq \$19,%rbp,%rdi
|
||||
add %rax,%r10
|
||||
mov 8*2(%rsi),%rax # f[2]
|
||||
adc %rdx,%r11
|
||||
mulq %rbp # f[2]*g[1]
|
||||
add %rax,%r12
|
||||
mov 8*3(%rsi),%rax # f[3]
|
||||
adc %rdx,%r13
|
||||
mulq %rbp # f[3]*g[1]
|
||||
mov 8*0(%rsp),%rbp # g[0]
|
||||
add %rax,%r14
|
||||
mov 8*4(%rsi),%rax # f[4]
|
||||
adc %rdx,%r15
|
||||
|
||||
mulq %rdi # f[4]*g[1]*19
|
||||
add %rax,%rbx
|
||||
mov 8*1(%rsi),%rax # f[1]
|
||||
adc %rdx,%rcx
|
||||
mul %rbp # f[1]*g[0]
|
||||
add %rax,%r8
|
||||
mov 8*2(%rsi),%rax # f[2]
|
||||
adc %rdx,%r9
|
||||
mul %rbp # f[2]*g[0]
|
||||
add %rax,%r10
|
||||
mov 8*3(%rsi),%rax # f[3]
|
||||
adc %rdx,%r11
|
||||
mul %rbp # f[3]*g[0]
|
||||
add %rax,%r12
|
||||
mov 8*4(%rsi),%rax # f[4]
|
||||
adc %rdx,%r13
|
||||
mulq %rbp # f[4]*g[0]
|
||||
add %rax,%r14
|
||||
adc %rdx,%r15
|
||||
|
||||
mov 8*4(%rsp),%rdi # restore 1st argument
|
||||
jmp .Lreduce51
|
||||
.size x25519_fe51_mul,.-x25519_fe51_mul
|
||||
|
||||
.globl x25519_fe51_sqr
|
||||
.type x25519_fe51_sqr,\@function,2
|
||||
.align 32
|
||||
x25519_fe51_sqr:
|
||||
push %rbp
|
||||
push %rbx
|
||||
push %r12
|
||||
push %r13
|
||||
push %r14
|
||||
push %r15
|
||||
lea -8*5(%rsp),%rsp
|
||||
|
||||
mov 8*0(%rsi),%rax # g[0]
|
||||
mov 8*2(%rsi),%r15 # g[2]
|
||||
mov 8*4(%rsi),%rbp # g[4]
|
||||
|
||||
mov %rdi,8*4(%rsp) # offload 1st argument
|
||||
lea (%rax,%rax),%r14
|
||||
mulq %rax # g[0]*g[0]
|
||||
mov %rax,%rbx
|
||||
mov 8*1(%rsi),%rax # g[1]
|
||||
mov %rdx,%rcx
|
||||
mulq %r14 # 2*g[0]*g[1]
|
||||
mov %rax,%r8
|
||||
mov %r15,%rax
|
||||
mov %r15,8*0(%rsp) # offload g[2]
|
||||
mov %rdx,%r9
|
||||
mulq %r14 # 2*g[0]*g[2]
|
||||
mov %rax,%r10
|
||||
mov 8*3(%rsi),%rax
|
||||
mov %rdx,%r11
|
||||
imulq \$19,%rbp,%rdi # g[4]*19
|
||||
mulq %r14 # 2*g[0]*g[3]
|
||||
mov %rax,%r12
|
||||
mov %rbp,%rax
|
||||
mov %rdx,%r13
|
||||
mulq %r14 # 2*g[0]*g[4]
|
||||
mov %rax,%r14
|
||||
mov %rbp,%rax
|
||||
mov %rdx,%r15
|
||||
|
||||
mulq %rdi # g[4]*g[4]*19
|
||||
add %rax,%r12
|
||||
mov 8*1(%rsi),%rax # g[1]
|
||||
adc %rdx,%r13
|
||||
|
||||
mov 8*3(%rsi),%rsi # g[3]
|
||||
lea (%rax,%rax),%rbp
|
||||
mulq %rax # g[1]*g[1]
|
||||
add %rax,%r10
|
||||
mov 8*0(%rsp),%rax # g[2]
|
||||
adc %rdx,%r11
|
||||
mulq %rbp # 2*g[1]*g[2]
|
||||
add %rax,%r12
|
||||
mov %rbp,%rax
|
||||
adc %rdx,%r13
|
||||
mulq %rsi # 2*g[1]*g[3]
|
||||
add %rax,%r14
|
||||
mov %rbp,%rax
|
||||
adc %rdx,%r15
|
||||
imulq \$19,%rsi,%rbp # g[3]*19
|
||||
mulq %rdi # 2*g[1]*g[4]*19
|
||||
add %rax,%rbx
|
||||
lea (%rsi,%rsi),%rax
|
||||
adc %rdx,%rcx
|
||||
|
||||
mulq %rdi # 2*g[3]*g[4]*19
|
||||
add %rax,%r10
|
||||
mov %rsi,%rax
|
||||
adc %rdx,%r11
|
||||
mulq %rbp # g[3]*g[3]*19
|
||||
add %rax,%r8
|
||||
mov 8*0(%rsp),%rax # g[2]
|
||||
adc %rdx,%r9
|
||||
|
||||
lea (%rax,%rax),%rsi
|
||||
mulq %rax # g[2]*g[2]
|
||||
add %rax,%r14
|
||||
mov %rbp,%rax
|
||||
adc %rdx,%r15
|
||||
mulq %rsi # 2*g[2]*g[3]*19
|
||||
add %rax,%rbx
|
||||
mov %rsi,%rax
|
||||
adc %rdx,%rcx
|
||||
mulq %rdi # 2*g[2]*g[4]*19
|
||||
add %rax,%r8
|
||||
adc %rdx,%r9
|
||||
|
||||
mov 8*4(%rsp),%rdi # restore 1st argument
|
||||
jmp .Lreduce51
|
||||
|
||||
.align 32
|
||||
.Lreduce51:
|
||||
mov \$0x7ffffffffffff,%rbp
|
||||
|
||||
mov %r10,%rdx
|
||||
shr \$51,%r10
|
||||
shl \$13,%r11
|
||||
and %rbp,%rdx # %rdx = g2 = h2 & mask
|
||||
or %r10,%r11 # h2>>51
|
||||
add %r11,%r12
|
||||
adc \$0,%r13 # h3 += h2>>51
|
||||
|
||||
mov %rbx,%rax
|
||||
shr \$51,%rbx
|
||||
shl \$13,%rcx
|
||||
and %rbp,%rax # %rax = g0 = h0 & mask
|
||||
or %rbx,%rcx # h0>>51
|
||||
add %rcx,%r8 # h1 += h0>>51
|
||||
adc \$0,%r9
|
||||
|
||||
mov %r12,%rbx
|
||||
shr \$51,%r12
|
||||
shl \$13,%r13
|
||||
and %rbp,%rbx # %rbx = g3 = h3 & mask
|
||||
or %r12,%r13 # h3>>51
|
||||
add %r13,%r14 # h4 += h3>>51
|
||||
adc \$0,%r15
|
||||
|
||||
mov %r8,%rcx
|
||||
shr \$51,%r8
|
||||
shl \$13,%r9
|
||||
and %rbp,%rcx # %rcx = g1 = h1 & mask
|
||||
or %r8,%r9
|
||||
add %r9,%rdx # g2 += h1>>51
|
||||
|
||||
mov %r14,%r10
|
||||
shr \$51,%r14
|
||||
shl \$13,%r15
|
||||
and %rbp,%r10 # %r10 = g4 = h0 & mask
|
||||
or %r14,%r15 # h0>>51
|
||||
|
||||
lea (%r15,%r15,8),%r14
|
||||
lea (%r15,%r14,2),%r15
|
||||
add %r15,%rax # g0 += (h0>>51)*19
|
||||
|
||||
mov %rdx,%r8
|
||||
and %rbp,%rdx # g2 &= mask
|
||||
shr \$51,%r8
|
||||
add %r8,%rbx # g3 += g2>>51
|
||||
|
||||
mov %rax,%r9
|
||||
and %rbp,%rax # g0 &= mask
|
||||
shr \$51,%r9
|
||||
add %r9,%rcx # g1 += g0>>51
|
||||
|
||||
mov %rax,8*0(%rdi) # save the result
|
||||
mov %rcx,8*1(%rdi)
|
||||
mov %rdx,8*2(%rdi)
|
||||
mov %rbx,8*3(%rdi)
|
||||
mov %r10,8*4(%rdi)
|
||||
|
||||
mov 8*5(%rsp),%r15
|
||||
mov 8*6(%rsp),%r14
|
||||
mov 8*7(%rsp),%r13
|
||||
mov 8*8(%rsp),%r12
|
||||
mov 8*9(%rsp),%rbx
|
||||
mov 8*10(%rsp),%rbp
|
||||
lea 8*11(%rsp),%rsp
|
||||
ret
|
||||
.size x25519_fe51_sqr,.-x25519_fe51_sqr
|
||||
|
||||
.globl x25519_fe51_mul121666
|
||||
.type x25519_fe51_mul121666,\@function,2
|
||||
.align 32
|
||||
x25519_fe51_mul121666:
|
||||
push %rbp
|
||||
push %rbx
|
||||
push %r12
|
||||
push %r13
|
||||
push %r14
|
||||
push %r15
|
||||
mov \$121666,%eax
|
||||
lea -8*5(%rsp),%rsp
|
||||
|
||||
mulq 8*0(%rsi)
|
||||
mov %rax,%rbx # %rbx:%rcx = h0
|
||||
mov \$121666,%eax
|
||||
mov %rdx,%rcx
|
||||
mulq 8*1(%rsi)
|
||||
mov %rax,%r8 # %r8:%r9 = h1
|
||||
mov \$121666,%eax
|
||||
mov %rdx,%r9
|
||||
mulq 8*2(%rsi)
|
||||
mov %rax,%r10 # %r10:%r11 = h2
|
||||
mov \$121666,%eax
|
||||
mov %rdx,%r11
|
||||
mulq 8*3(%rsi)
|
||||
mov %rax,%r12 # %r12:%r13 = h3
|
||||
mov \$121666,%eax # f[0]
|
||||
mov %rdx,%r13
|
||||
mulq 8*4(%rsi)
|
||||
mov %rax,%r14 # %r14:%r15 = h4
|
||||
mov %rdx,%r15
|
||||
|
||||
jmp .Lreduce51
|
||||
.size x25519_fe51_mul121666,.-x25519_fe51_mul121666
|
||||
___
|
||||
########################################################################
|
||||
# Base 2^64 subroutines modulo 2*(2^255-19)
|
||||
#
|
||||
if ($addx) {
|
||||
my ($acc0,$acc1,$acc2,$acc3,$acc4,$acc5,$acc6,$acc7) = map("%r$_",(8..15));
|
||||
|
||||
$code.=<<___;
|
||||
.extern OPENSSL_ia32cap_P
|
||||
.globl x25519_fe64_eligible
|
||||
.type x25519_fe64_eligible,\@abi-omnipotent
|
||||
.align 32
|
||||
x25519_fe64_eligible:
|
||||
mov OPENSSL_ia32cap_P+8(%rip),%ecx
|
||||
xor %eax,%eax
|
||||
and \$0x80100,%ecx
|
||||
cmp \$0x80100,%ecx
|
||||
cmove %ecx,%eax
|
||||
ret
|
||||
.size x25519_fe64_eligible,.-x25519_fe64_eligible
|
||||
|
||||
.globl x25519_fe64_mul
|
||||
.type x25519_fe64_mul,\@function,3
|
||||
.align 32
|
||||
x25519_fe64_mul:
|
||||
push %rbp
|
||||
push %rbx
|
||||
push %r12
|
||||
push %r13
|
||||
push %r14
|
||||
push %r15
|
||||
push %rdi # offload dst
|
||||
lea -8*2(%rsp),%rsp
|
||||
|
||||
mov %rdx,%rax
|
||||
mov 8*0(%rdx),%rbp # b[0]
|
||||
mov 8*0(%rsi),%rdx # a[0]
|
||||
mov 8*1(%rax),%rcx # b[1]
|
||||
mov 8*2(%rax),$acc6 # b[2]
|
||||
mov 8*3(%rax),$acc7 # b[3]
|
||||
|
||||
mulx %rbp,$acc0,%rax # a[0]*b[0]
|
||||
xor %edi,%edi # cf=0,of=0
|
||||
mulx %rcx,$acc1,%rbx # a[0]*b[1]
|
||||
adcx %rax,$acc1
|
||||
mulx $acc6,$acc2,%rax # a[0]*b[2]
|
||||
adcx %rbx,$acc2
|
||||
mulx $acc7,$acc3,$acc4 # a[0]*b[3]
|
||||
mov 8*1(%rsi),%rdx # a[1]
|
||||
adcx %rax,$acc3
|
||||
mov $acc6,(%rsp) # offload b[2]
|
||||
adcx %rdi,$acc4 # cf=0
|
||||
|
||||
mulx %rbp,%rax,%rbx # a[1]*b[0]
|
||||
adox %rax,$acc1
|
||||
adcx %rbx,$acc2
|
||||
mulx %rcx,%rax,%rbx # a[1]*b[1]
|
||||
adox %rax,$acc2
|
||||
adcx %rbx,$acc3
|
||||
mulx $acc6,%rax,%rbx # a[1]*b[2]
|
||||
adox %rax,$acc3
|
||||
adcx %rbx,$acc4
|
||||
mulx $acc7,%rax,$acc5 # a[1]*b[3]
|
||||
mov 8*2(%rsi),%rdx # a[2]
|
||||
adox %rax,$acc4
|
||||
adcx %rdi,$acc5 # cf=0
|
||||
adox %rdi,$acc5 # of=0
|
||||
|
||||
mulx %rbp,%rax,%rbx # a[2]*b[0]
|
||||
adcx %rax,$acc2
|
||||
adox %rbx,$acc3
|
||||
mulx %rcx,%rax,%rbx # a[2]*b[1]
|
||||
adcx %rax,$acc3
|
||||
adox %rbx,$acc4
|
||||
mulx $acc6,%rax,%rbx # a[2]*b[2]
|
||||
adcx %rax,$acc4
|
||||
adox %rbx,$acc5
|
||||
mulx $acc7,%rax,$acc6 # a[2]*b[3]
|
||||
mov 8*3(%rsi),%rdx # a[3]
|
||||
adcx %rax,$acc5
|
||||
adox %rdi,$acc6 # of=0
|
||||
adcx %rdi,$acc6 # cf=0
|
||||
|
||||
mulx %rbp,%rax,%rbx # a[3]*b[0]
|
||||
adox %rax,$acc3
|
||||
adcx %rbx,$acc4
|
||||
mulx %rcx,%rax,%rbx # a[3]*b[1]
|
||||
adox %rax,$acc4
|
||||
adcx %rbx,$acc5
|
||||
mulx (%rsp),%rax,%rbx # a[3]*b[2]
|
||||
adox %rax,$acc5
|
||||
adcx %rbx,$acc6
|
||||
mulx $acc7,%rax,$acc7 # a[3]*b[3]
|
||||
mov \$38,%edx
|
||||
adox %rax,$acc6
|
||||
adcx %rdi,$acc7 # cf=0
|
||||
adox %rdi,$acc7 # of=0
|
||||
|
||||
jmp .Lreduce64
|
||||
.size x25519_fe64_mul,.-x25519_fe64_mul
|
||||
|
||||
.globl x25519_fe64_sqr
|
||||
.type x25519_fe64_sqr,\@function,2
|
||||
.align 32
|
||||
x25519_fe64_sqr:
|
||||
push %rbp
|
||||
push %rbx
|
||||
push %r12
|
||||
push %r13
|
||||
push %r14
|
||||
push %r15
|
||||
push %rdi # offload dst
|
||||
lea -8*2(%rsp),%rsp
|
||||
|
||||
mov 8*0(%rsi),%rdx # a[0]
|
||||
mov 8*1(%rsi),%rcx # a[1]
|
||||
mov 8*2(%rsi),%rbp # a[2]
|
||||
mov 8*3(%rsi),%rsi # a[3]
|
||||
|
||||
################################################################
|
||||
mulx %rdx,$acc0,$acc7 # a[0]*a[0]
|
||||
mulx %rcx,$acc1,%rax # a[0]*a[1]
|
||||
xor %edi,%edi # cf=0,of=0
|
||||
mulx %rbp,$acc2,%rbx # a[0]*a[2]
|
||||
adcx %rax,$acc2
|
||||
mulx %rsi,$acc3,$acc4 # a[0]*a[3]
|
||||
mov %rcx,%rdx # a[1]
|
||||
adcx %rbx,$acc3
|
||||
adcx %rdi,$acc4 # cf=0
|
||||
|
||||
################################################################
|
||||
mulx %rbp,%rax,%rbx # a[1]*a[2]
|
||||
adox %rax,$acc3
|
||||
adcx %rbx,$acc4
|
||||
mulx %rsi,%rax,$acc5 # a[1]*a[3]
|
||||
mov %rbp,%rdx # a[2]
|
||||
adox %rax,$acc4
|
||||
adcx %rdi,$acc5
|
||||
|
||||
################################################################
|
||||
mulx %rsi,%rax,$acc6 # a[2]*a[3]
|
||||
mov %rcx,%rdx # a[1]
|
||||
adox %rax,$acc5
|
||||
adcx %rdi,$acc6 # cf=0
|
||||
adox %rdi,$acc6 # of=0
|
||||
|
||||
adcx $acc1,$acc1 # acc1:6<<1
|
||||
adox $acc7,$acc1
|
||||
adcx $acc2,$acc2
|
||||
mulx %rdx,%rax,%rbx # a[1]*a[1]
|
||||
mov %rbp,%rdx # a[2]
|
||||
adcx $acc3,$acc3
|
||||
adox %rax,$acc2
|
||||
adcx $acc4,$acc4
|
||||
adox %rbx,$acc3
|
||||
mulx %rdx,%rax,%rbx # a[2]*a[2]
|
||||
mov %rsi,%rdx # a[3]
|
||||
adcx $acc5,$acc5
|
||||
adox %rax,$acc4
|
||||
adcx $acc6,$acc6
|
||||
adox %rbx,$acc5
|
||||
mulx %rdx,%rax,$acc7 # a[3]*a[3]
|
||||
mov \$38,%edx
|
||||
adox %rax,$acc6
|
||||
adcx %rdi,$acc7 # cf=0
|
||||
adox %rdi,$acc7 # of=0
|
||||
jmp .Lreduce64
|
||||
|
||||
.align 32
|
||||
.Lreduce64:
|
||||
mulx $acc4,%rax,%rbx
|
||||
adcx %rax,$acc0
|
||||
adox %rbx,$acc1
|
||||
mulx $acc5,%rax,%rbx
|
||||
adcx %rax,$acc1
|
||||
adox %rbx,$acc2
|
||||
mulx $acc6,%rax,%rbx
|
||||
adcx %rax,$acc2
|
||||
adox %rbx,$acc3
|
||||
mulx $acc7,%rax,$acc4
|
||||
adcx %rax,$acc3
|
||||
adox %rdi,$acc4
|
||||
adcx %rdi,$acc4
|
||||
|
||||
mov 8*2(%rsp),%rdi # restore dst
|
||||
imulq %rdx,$acc4
|
||||
|
||||
add $acc4,$acc0
|
||||
adc \$0,$acc1
|
||||
adc \$0,$acc2
|
||||
adc \$0,$acc3
|
||||
|
||||
sbb %rax,%rax # cf -> mask
|
||||
and \$38,%rax
|
||||
|
||||
add %rax,$acc0
|
||||
adc \$0,$acc1
|
||||
mov $acc0,8*0(%rdi)
|
||||
adc \$0,$acc2
|
||||
mov $acc1,8*1(%rdi)
|
||||
adc \$0,$acc3
|
||||
mov $acc2,8*2(%rdi)
|
||||
mov $acc3,8*3(%rdi)
|
||||
|
||||
mov 8*3(%rsp),%r15
|
||||
mov 8*4(%rsp),%r14
|
||||
mov 8*5(%rsp),%r13
|
||||
mov 8*6(%rsp),%r12
|
||||
mov 8*7(%rsp),%rbx
|
||||
mov 8*8(%rsp),%rbp
|
||||
lea 8*9(%rsp),%rsp
|
||||
ret
|
||||
.size x25519_fe64_sqr,.-x25519_fe64_sqr
|
||||
|
||||
.globl x25519_fe64_mul121666
|
||||
.type x25519_fe64_mul121666,\@function,2
|
||||
.align 32
|
||||
x25519_fe64_mul121666:
|
||||
mov \$121666,%edx
|
||||
mulx 8*0(%rsi),$acc0,%rcx
|
||||
mulx 8*1(%rsi),$acc1,%rax
|
||||
add %rcx,$acc1
|
||||
mulx 8*2(%rsi),$acc2,%rcx
|
||||
adc %rax,$acc2
|
||||
mulx 8*3(%rsi),$acc3,%rax
|
||||
adc %rcx,$acc3
|
||||
adc \$0,%rax
|
||||
|
||||
imulq \$38,%rax,%rax
|
||||
|
||||
add %rax,$acc0
|
||||
adc \$0,$acc1
|
||||
adc \$0,$acc2
|
||||
adc \$0,$acc3
|
||||
|
||||
sbb %rax,%rax # cf -> mask
|
||||
and \$38,%rax
|
||||
|
||||
add %rax,$acc0
|
||||
adc \$0,$acc1
|
||||
mov $acc0,8*0(%rdi)
|
||||
adc \$0,$acc2
|
||||
mov $acc1,8*1(%rdi)
|
||||
adc \$0,$acc3
|
||||
mov $acc2,8*2(%rdi)
|
||||
mov $acc3,8*3(%rdi)
|
||||
|
||||
ret
|
||||
.size x25519_fe64_mul121666,.-x25519_fe64_mul121666
|
||||
|
||||
.globl x25519_fe64_add
|
||||
.type x25519_fe64_add,\@function,3
|
||||
.align 32
|
||||
x25519_fe64_add:
|
||||
mov 8*0(%rsi),$acc0
|
||||
mov 8*1(%rsi),$acc1
|
||||
mov 8*2(%rsi),$acc2
|
||||
mov 8*3(%rsi),$acc3
|
||||
|
||||
add 8*0(%rdx),$acc0
|
||||
adc 8*1(%rdx),$acc1
|
||||
adc 8*2(%rdx),$acc2
|
||||
adc 8*3(%rdx),$acc3
|
||||
|
||||
sbb %rax,%rax # cf -> mask
|
||||
and \$38,%rax
|
||||
|
||||
add %rax,$acc0
|
||||
adc \$0,$acc1
|
||||
mov $acc0,8*0(%rdi)
|
||||
adc \$0,$acc2
|
||||
mov $acc1,8*1(%rdi)
|
||||
adc \$0,$acc3
|
||||
mov $acc2,8*2(%rdi)
|
||||
mov $acc3,8*3(%rdi)
|
||||
|
||||
ret
|
||||
.size x25519_fe64_add,.-x25519_fe64_add
|
||||
|
||||
.globl x25519_fe64_sub
|
||||
.type x25519_fe64_sub,\@function,3
|
||||
.align 32
|
||||
x25519_fe64_sub:
|
||||
mov 8*0(%rsi),$acc0
|
||||
mov 8*1(%rsi),$acc1
|
||||
mov 8*2(%rsi),$acc2
|
||||
mov 8*3(%rsi),$acc3
|
||||
|
||||
sub 8*0(%rdx),$acc0
|
||||
sbb 8*1(%rdx),$acc1
|
||||
sbb 8*2(%rdx),$acc2
|
||||
sbb 8*3(%rdx),$acc3
|
||||
|
||||
sbb %rax,%rax # cf -> mask
|
||||
and \$38,%rax
|
||||
|
||||
sub %rax,$acc0
|
||||
sbb \$0,$acc1
|
||||
mov $acc0,8*0(%rdi)
|
||||
sbb \$0,$acc2
|
||||
mov $acc1,8*1(%rdi)
|
||||
sbb \$0,$acc3
|
||||
mov $acc2,8*2(%rdi)
|
||||
mov $acc3,8*3(%rdi)
|
||||
|
||||
ret
|
||||
.size x25519_fe64_sub,.-x25519_fe64_sub
|
||||
|
||||
.globl x25519_fe64_tobytes
|
||||
.type x25519_fe64_tobytes,\@function,2
|
||||
.align 32
|
||||
x25519_fe64_tobytes:
|
||||
mov 8*0(%rsi),$acc0
|
||||
mov 8*1(%rsi),$acc1
|
||||
mov 8*2(%rsi),$acc2
|
||||
mov 8*3(%rsi),$acc3
|
||||
|
||||
################################# reduction modulo 2^255-19
|
||||
lea ($acc3,$acc3),%rax
|
||||
sar \$63,$acc3 # most significant bit -> mask
|
||||
shr \$1,%rax # most significant bit cleared
|
||||
and \$19,$acc3
|
||||
|
||||
add $acc3,$acc0
|
||||
adc \$0,$acc1
|
||||
adc \$0,$acc2
|
||||
adc \$0,%rax
|
||||
|
||||
lea (%rax,%rax),$acc3
|
||||
sar \$63,%rax # most significant bit -> mask
|
||||
shr \$1,$acc3 # most significant bit cleared
|
||||
and \$19,%rax
|
||||
|
||||
add %rax,$acc0
|
||||
adc \$0,$acc1
|
||||
adc \$0,$acc2
|
||||
adc \$0,$acc3
|
||||
|
||||
mov $acc0,8*0(%rdi)
|
||||
mov $acc1,8*1(%rdi)
|
||||
mov $acc2,8*2(%rdi)
|
||||
mov $acc3,8*3(%rdi)
|
||||
|
||||
ret
|
||||
.size x25519_fe64_tobytes,.-x25519_fe64_tobytes
|
||||
___
|
||||
} else {
|
||||
$code.=<<___;
|
||||
.globl x25519_fe64_eligible
|
||||
.type x25519_fe64_eligible,\@abi-omnipotent
|
||||
.align 32
|
||||
x25519_fe64_eligible:
|
||||
xor %eax,%eax
|
||||
ret
|
||||
.size x25519_fe64_eligible,.-x25519_fe64_eligible
|
||||
|
||||
.globl x25519_fe64_mul
|
||||
.type x25519_fe64_mul,\@abi-omnipotent
|
||||
.globl x25519_fe64_sqr
|
||||
.globl x25519_fe64_mul121666
|
||||
.globl x25519_fe64_add
|
||||
.globl x25519_fe64_sub
|
||||
.globl x25519_fe64_tobytes
|
||||
x25519_fe64_mul:
|
||||
x25519_fe64_sqr:
|
||||
x25519_fe64_mul121666:
|
||||
x25519_fe64_add:
|
||||
x25519_fe64_sub:
|
||||
x25519_fe64_tobytes:
|
||||
.byte 0x0f,0x0b # ud2
|
||||
ret
|
||||
.size x25519_fe64_mul,.-x25519_fe64_mul
|
||||
___
|
||||
}
|
||||
$code.=<<___;
|
||||
.asciz "X25519 primitives for x86_64, CRYPTOGAMS by <appro\@openssl.org>"
|
||||
___
|
||||
|
||||
$code =~ s/\`([^\`]*)\`/eval $1/gem;
|
||||
print $code;
|
||||
close $STDOUT;
|
||||
+14
-1
@@ -6,9 +6,12 @@ SOURCE[../../libcrypto]=\
|
||||
ecp_nistp224.c ecp_nistp256.c ecp_nistp521.c ecp_nistputil.c \
|
||||
ecp_oct.c ec2_oct.c ec_oct.c ec_kmeth.c ecdh_ossl.c ecdh_kdf.c \
|
||||
ecdsa_ossl.c ecdsa_sign.c ecdsa_vrf.c curve25519.c ecx_meth.c \
|
||||
curve448/arch_32/f_impl.c curve448/f_generic.c curve448/scalar.c \
|
||||
curve448/curve448_tables.c curve448/eddsa.c curve448/curve448.c \
|
||||
{- $target{ec_asm_src} -}
|
||||
|
||||
GENERATE[ecp_nistz256-x86.s]=asm/ecp_nistz256-x86.pl $(PERLASM_SCHEME) $(CFLAGS) $(LIB_CFLAGS) $(PROCESSOR)
|
||||
GENERATE[ecp_nistz256-x86.s]=asm/ecp_nistz256-x86.pl \
|
||||
$(PERLASM_SCHEME) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR)
|
||||
|
||||
GENERATE[ecp_nistz256-x86_64.s]=asm/ecp_nistz256-x86_64.pl $(PERLASM_SCHEME)
|
||||
|
||||
@@ -21,8 +24,18 @@ GENERATE[ecp_nistz256-armv4.S]=asm/ecp_nistz256-armv4.pl $(PERLASM_SCHEME)
|
||||
INCLUDE[ecp_nistz256-armv4.o]=..
|
||||
GENERATE[ecp_nistz256-armv8.S]=asm/ecp_nistz256-armv8.pl $(PERLASM_SCHEME)
|
||||
INCLUDE[ecp_nistz256-armv8.o]=..
|
||||
GENERATE[ecp_nistz256-ppc64.s]=asm/ecp_nistz256-ppc64.pl $(PERLASM_SCHEME)
|
||||
|
||||
GENERATE[x25519-x86_64.s]=asm/x25519-x86_64.pl $(PERLASM_SCHEME)
|
||||
|
||||
BEGINRAW[Makefile]
|
||||
{- $builddir -}/ecp_nistz256-%.S: {- $sourcedir -}/asm/ecp_nistz256-%.pl
|
||||
CC="$(CC)" $(PERL) $< $(PERLASM_SCHEME) $@
|
||||
ENDRAW[Makefile]
|
||||
|
||||
INCLUDE[curve448/arch_32/f_impl.o]=curve448/arch_32 curve448
|
||||
INCLUDE[curve448/f_generic.o]=curve448/arch_32 curve448
|
||||
INCLUDE[curve448/scalar.o]=curve448/arch_32 curve448
|
||||
INCLUDE[curve448/curve448_tables.o]=curve448/arch_32 curve448
|
||||
INCLUDE[curve448/eddsa.o]=curve448/arch_32 curve448
|
||||
INCLUDE[curve448/curve448.o]=curve448/arch_32 curve448
|
||||
+1726
-154
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2016-2018 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
|
||||
@@ -11,15 +11,18 @@
|
||||
#include "ec_lcl.h"
|
||||
#include <openssl/sha.h>
|
||||
|
||||
#if !defined(PEDANTIC) && \
|
||||
(defined(__SIZEOF_INT128__) && __SIZEOF_INT128__==16)
|
||||
#if defined(X25519_ASM) \
|
||||
|| ( (defined(__SIZEOF_INT128__) && __SIZEOF_INT128__ == 16) \
|
||||
&& !defined(__sparc__) )
|
||||
/*
|
||||
* Base 2^51 implementation.
|
||||
*/
|
||||
# define BASE_2_51_IMPLEMENTED
|
||||
|
||||
typedef uint64_t fe51[5];
|
||||
typedef unsigned __int128 u128;
|
||||
# if !defined(X25519_ASM)
|
||||
typedef __uint128_t u128;
|
||||
# endif
|
||||
|
||||
static const uint64_t MASK51 = 0x7ffffffffffff;
|
||||
|
||||
@@ -97,40 +100,284 @@ static void fe51_tobytes(uint8_t *s, const fe51 h)
|
||||
h4 &= MASK51;
|
||||
|
||||
/* smash */
|
||||
s[0] = h0 >> 0;
|
||||
s[1] = h0 >> 8;
|
||||
s[2] = h0 >> 16;
|
||||
s[3] = h0 >> 24;
|
||||
s[4] = h0 >> 32;
|
||||
s[5] = h0 >> 40;
|
||||
s[6] = (h0 >> 48) | ((uint32_t)h1 << 3);
|
||||
s[7] = h1 >> 5;
|
||||
s[8] = h1 >> 13;
|
||||
s[9] = h1 >> 21;
|
||||
s[10] = h1 >> 29;
|
||||
s[11] = h1 >> 37;
|
||||
s[12] = (h1 >> 45) | ((uint32_t)h2 << 6);
|
||||
s[13] = h2 >> 2;
|
||||
s[14] = h2 >> 10;
|
||||
s[15] = h2 >> 18;
|
||||
s[16] = h2 >> 26;
|
||||
s[17] = h2 >> 34;
|
||||
s[18] = h2 >> 42;
|
||||
s[19] = (h2 >> 50) | ((uint32_t)h3 << 1);
|
||||
s[20] = h3 >> 7;
|
||||
s[21] = h3 >> 15;
|
||||
s[22] = h3 >> 23;
|
||||
s[23] = h3 >> 31;
|
||||
s[24] = h3 >> 39;
|
||||
s[25] = (h3 >> 47) | ((uint32_t)h4 << 4);
|
||||
s[26] = h4 >> 4;
|
||||
s[27] = h4 >> 12;
|
||||
s[28] = h4 >> 20;
|
||||
s[29] = h4 >> 28;
|
||||
s[30] = h4 >> 36;
|
||||
s[31] = h4 >> 44;
|
||||
s[0] = (uint8_t)(h0 >> 0);
|
||||
s[1] = (uint8_t)(h0 >> 8);
|
||||
s[2] = (uint8_t)(h0 >> 16);
|
||||
s[3] = (uint8_t)(h0 >> 24);
|
||||
s[4] = (uint8_t)(h0 >> 32);
|
||||
s[5] = (uint8_t)(h0 >> 40);
|
||||
s[6] = (uint8_t)((h0 >> 48) | ((uint32_t)h1 << 3));
|
||||
s[7] = (uint8_t)(h1 >> 5);
|
||||
s[8] = (uint8_t)(h1 >> 13);
|
||||
s[9] = (uint8_t)(h1 >> 21);
|
||||
s[10] = (uint8_t)(h1 >> 29);
|
||||
s[11] = (uint8_t)(h1 >> 37);
|
||||
s[12] = (uint8_t)((h1 >> 45) | ((uint32_t)h2 << 6));
|
||||
s[13] = (uint8_t)(h2 >> 2);
|
||||
s[14] = (uint8_t)(h2 >> 10);
|
||||
s[15] = (uint8_t)(h2 >> 18);
|
||||
s[16] = (uint8_t)(h2 >> 26);
|
||||
s[17] = (uint8_t)(h2 >> 34);
|
||||
s[18] = (uint8_t)(h2 >> 42);
|
||||
s[19] = (uint8_t)((h2 >> 50) | ((uint32_t)h3 << 1));
|
||||
s[20] = (uint8_t)(h3 >> 7);
|
||||
s[21] = (uint8_t)(h3 >> 15);
|
||||
s[22] = (uint8_t)(h3 >> 23);
|
||||
s[23] = (uint8_t)(h3 >> 31);
|
||||
s[24] = (uint8_t)(h3 >> 39);
|
||||
s[25] = (uint8_t)((h3 >> 47) | ((uint32_t)h4 << 4));
|
||||
s[26] = (uint8_t)(h4 >> 4);
|
||||
s[27] = (uint8_t)(h4 >> 12);
|
||||
s[28] = (uint8_t)(h4 >> 20);
|
||||
s[29] = (uint8_t)(h4 >> 28);
|
||||
s[30] = (uint8_t)(h4 >> 36);
|
||||
s[31] = (uint8_t)(h4 >> 44);
|
||||
}
|
||||
|
||||
# ifdef X25519_ASM
|
||||
void x25519_fe51_mul(fe51 h, const fe51 f, const fe51 g);
|
||||
void x25519_fe51_sqr(fe51 h, const fe51 f);
|
||||
void x25519_fe51_mul121666(fe51 h, fe51 f);
|
||||
# define fe51_mul x25519_fe51_mul
|
||||
# define fe51_sq x25519_fe51_sqr
|
||||
# define fe51_mul121666 x25519_fe51_mul121666
|
||||
|
||||
# if defined(__x86_64) || defined(__x86_64__) || \
|
||||
defined(_M_AMD64) || defined(_M_X64)
|
||||
|
||||
# define BASE_2_64_IMPLEMENTED
|
||||
|
||||
typedef uint64_t fe64[4];
|
||||
|
||||
int x25519_fe64_eligible();
|
||||
|
||||
/*
|
||||
* There are no reference C implementations for this radix.
|
||||
*/
|
||||
void x25519_fe64_mul(fe64 h, const fe64 f, const fe64 g);
|
||||
void x25519_fe64_sqr(fe64 h, const fe64 f);
|
||||
void x25519_fe64_mul121666(fe64 h, fe64 f);
|
||||
void x25519_fe64_add(fe64 h, const fe64 f, const fe64 g);
|
||||
void x25519_fe64_sub(fe64 h, const fe64 f, const fe64 g);
|
||||
void x25519_fe64_tobytes(uint8_t *s, const fe64 f);
|
||||
# define fe64_mul x25519_fe64_mul
|
||||
# define fe64_sqr x25519_fe64_sqr
|
||||
# define fe64_mul121666 x25519_fe64_mul121666
|
||||
# define fe64_add x25519_fe64_add
|
||||
# define fe64_sub x25519_fe64_sub
|
||||
# define fe64_tobytes x25519_fe64_tobytes
|
||||
|
||||
static uint64_t load_8(const uint8_t *in)
|
||||
{
|
||||
uint64_t result;
|
||||
|
||||
result = in[0];
|
||||
result |= ((uint64_t)in[1]) << 8;
|
||||
result |= ((uint64_t)in[2]) << 16;
|
||||
result |= ((uint64_t)in[3]) << 24;
|
||||
result |= ((uint64_t)in[4]) << 32;
|
||||
result |= ((uint64_t)in[5]) << 40;
|
||||
result |= ((uint64_t)in[6]) << 48;
|
||||
result |= ((uint64_t)in[7]) << 56;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void fe64_frombytes(fe64 h, const uint8_t *s)
|
||||
{
|
||||
h[0] = load_8(s);
|
||||
h[1] = load_8(s + 8);
|
||||
h[2] = load_8(s + 16);
|
||||
h[3] = load_8(s + 24) & 0x7fffffffffffffff;
|
||||
}
|
||||
|
||||
static void fe64_0(fe64 h)
|
||||
{
|
||||
h[0] = 0;
|
||||
h[1] = 0;
|
||||
h[2] = 0;
|
||||
h[3] = 0;
|
||||
}
|
||||
|
||||
static void fe64_1(fe64 h)
|
||||
{
|
||||
h[0] = 1;
|
||||
h[1] = 0;
|
||||
h[2] = 0;
|
||||
h[3] = 0;
|
||||
}
|
||||
|
||||
static void fe64_copy(fe64 h, const fe64 f)
|
||||
{
|
||||
h[0] = f[0];
|
||||
h[1] = f[1];
|
||||
h[2] = f[2];
|
||||
h[3] = f[3];
|
||||
}
|
||||
|
||||
static void fe64_cswap(fe64 f, fe64 g, unsigned int b)
|
||||
{
|
||||
int i;
|
||||
uint64_t mask = 0 - (uint64_t)b;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
uint64_t x = f[i] ^ g[i];
|
||||
x &= mask;
|
||||
f[i] ^= x;
|
||||
g[i] ^= x;
|
||||
}
|
||||
}
|
||||
|
||||
static void fe64_invert(fe64 out, const fe64 z)
|
||||
{
|
||||
fe64 t0;
|
||||
fe64 t1;
|
||||
fe64 t2;
|
||||
fe64 t3;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Compute z ** -1 = z ** (2 ** 255 - 19 - 2) with the exponent as
|
||||
* 2 ** 255 - 21 = (2 ** 5) * (2 ** 250 - 1) + 11.
|
||||
*/
|
||||
|
||||
/* t0 = z ** 2 */
|
||||
fe64_sqr(t0, z);
|
||||
|
||||
/* t1 = t0 ** (2 ** 2) = z ** 8 */
|
||||
fe64_sqr(t1, t0);
|
||||
fe64_sqr(t1, t1);
|
||||
|
||||
/* t1 = z * t1 = z ** 9 */
|
||||
fe64_mul(t1, z, t1);
|
||||
/* t0 = t0 * t1 = z ** 11 -- stash t0 away for the end. */
|
||||
fe64_mul(t0, t0, t1);
|
||||
|
||||
/* t2 = t0 ** 2 = z ** 22 */
|
||||
fe64_sqr(t2, t0);
|
||||
|
||||
/* t1 = t1 * t2 = z ** (2 ** 5 - 1) */
|
||||
fe64_mul(t1, t1, t2);
|
||||
|
||||
/* t2 = t1 ** (2 ** 5) = z ** ((2 ** 5) * (2 ** 5 - 1)) */
|
||||
fe64_sqr(t2, t1);
|
||||
for (i = 1; i < 5; ++i)
|
||||
fe64_sqr(t2, t2);
|
||||
|
||||
/* t1 = t1 * t2 = z ** ((2 ** 5 + 1) * (2 ** 5 - 1)) = z ** (2 ** 10 - 1) */
|
||||
fe64_mul(t1, t2, t1);
|
||||
|
||||
/* Continuing similarly... */
|
||||
|
||||
/* t2 = z ** (2 ** 20 - 1) */
|
||||
fe64_sqr(t2, t1);
|
||||
for (i = 1; i < 10; ++i)
|
||||
fe64_sqr(t2, t2);
|
||||
|
||||
fe64_mul(t2, t2, t1);
|
||||
|
||||
/* t2 = z ** (2 ** 40 - 1) */
|
||||
fe64_sqr(t3, t2);
|
||||
for (i = 1; i < 20; ++i)
|
||||
fe64_sqr(t3, t3);
|
||||
|
||||
fe64_mul(t2, t3, t2);
|
||||
|
||||
/* t2 = z ** (2 ** 10) * (2 ** 40 - 1) */
|
||||
for (i = 0; i < 10; ++i)
|
||||
fe64_sqr(t2, t2);
|
||||
|
||||
/* t1 = z ** (2 ** 50 - 1) */
|
||||
fe64_mul(t1, t2, t1);
|
||||
|
||||
/* t2 = z ** (2 ** 100 - 1) */
|
||||
fe64_sqr(t2, t1);
|
||||
for (i = 1; i < 50; ++i)
|
||||
fe64_sqr(t2, t2);
|
||||
|
||||
fe64_mul(t2, t2, t1);
|
||||
|
||||
/* t2 = z ** (2 ** 200 - 1) */
|
||||
fe64_sqr(t3, t2);
|
||||
for (i = 1; i < 100; ++i)
|
||||
fe64_sqr(t3, t3);
|
||||
|
||||
fe64_mul(t2, t3, t2);
|
||||
|
||||
/* t2 = z ** ((2 ** 50) * (2 ** 200 - 1) */
|
||||
for (i = 0; i < 50; ++i)
|
||||
fe64_sqr(t2, t2);
|
||||
|
||||
/* t1 = z ** (2 ** 250 - 1) */
|
||||
fe64_mul(t1, t2, t1);
|
||||
|
||||
/* t1 = z ** ((2 ** 5) * (2 ** 250 - 1)) */
|
||||
for (i = 0; i < 5; ++i)
|
||||
fe64_sqr(t1, t1);
|
||||
|
||||
/* Recall t0 = z ** 11; out = z ** (2 ** 255 - 21) */
|
||||
fe64_mul(out, t1, t0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Duplicate of original x25519_scalar_mult_generic, but using
|
||||
* fe64_* subroutines.
|
||||
*/
|
||||
static void x25519_scalar_mulx(uint8_t out[32], const uint8_t scalar[32],
|
||||
const uint8_t point[32])
|
||||
{
|
||||
fe64 x1, x2, z2, x3, z3, tmp0, tmp1;
|
||||
uint8_t e[32];
|
||||
unsigned swap = 0;
|
||||
int pos;
|
||||
|
||||
memcpy(e, scalar, 32);
|
||||
e[0] &= 0xf8;
|
||||
e[31] &= 0x7f;
|
||||
e[31] |= 0x40;
|
||||
fe64_frombytes(x1, point);
|
||||
fe64_1(x2);
|
||||
fe64_0(z2);
|
||||
fe64_copy(x3, x1);
|
||||
fe64_1(z3);
|
||||
|
||||
for (pos = 254; pos >= 0; --pos) {
|
||||
unsigned int b = 1 & (e[pos / 8] >> (pos & 7));
|
||||
|
||||
swap ^= b;
|
||||
fe64_cswap(x2, x3, swap);
|
||||
fe64_cswap(z2, z3, swap);
|
||||
swap = b;
|
||||
fe64_sub(tmp0, x3, z3);
|
||||
fe64_sub(tmp1, x2, z2);
|
||||
fe64_add(x2, x2, z2);
|
||||
fe64_add(z2, x3, z3);
|
||||
fe64_mul(z3, x2, tmp0);
|
||||
fe64_mul(z2, z2, tmp1);
|
||||
fe64_sqr(tmp0, tmp1);
|
||||
fe64_sqr(tmp1, x2);
|
||||
fe64_add(x3, z3, z2);
|
||||
fe64_sub(z2, z3, z2);
|
||||
fe64_mul(x2, tmp1, tmp0);
|
||||
fe64_sub(tmp1, tmp1, tmp0);
|
||||
fe64_sqr(z2, z2);
|
||||
fe64_mul121666(z3, tmp1);
|
||||
fe64_sqr(x3, x3);
|
||||
fe64_add(tmp0, tmp0, z3);
|
||||
fe64_mul(z3, x1, z2);
|
||||
fe64_mul(z2, tmp1, tmp0);
|
||||
}
|
||||
|
||||
fe64_invert(z2, z2);
|
||||
fe64_mul(x2, x2, z2);
|
||||
fe64_tobytes(out, x2);
|
||||
|
||||
OPENSSL_cleanse(e, sizeof(e));
|
||||
}
|
||||
# endif
|
||||
|
||||
# else
|
||||
|
||||
static void fe51_mul(fe51 h, const fe51 f, const fe51 g)
|
||||
{
|
||||
u128 h0, h1, h2, h3, h4;
|
||||
@@ -191,9 +438,9 @@ static void fe51_mul(fe51 h, const fe51 f, const fe51 g)
|
||||
|
||||
static void fe51_sq(fe51 h, const fe51 f)
|
||||
{
|
||||
# if defined(OPENSSL_SMALL_FOOTPRINT)
|
||||
# if defined(OPENSSL_SMALL_FOOTPRINT)
|
||||
fe51_mul(h, f, f);
|
||||
# else
|
||||
# else
|
||||
/* dedicated squaring gives 16-25% overall improvement */
|
||||
uint64_t g0 = f[0];
|
||||
uint64_t g1 = f[1];
|
||||
@@ -221,7 +468,7 @@ static void fe51_sq(fe51 h, const fe51 f)
|
||||
h2 += (u128)(g0 * 2) * g4;
|
||||
|
||||
h4 += (u128)g2 * g2; g2 *= 2;
|
||||
h0 += (u128)g2 * g3;
|
||||
h0 += (u128)g2 * g3;
|
||||
h1 += (u128)g2 * g4;
|
||||
|
||||
/* partial [lazy] reduction */
|
||||
@@ -240,9 +487,36 @@ static void fe51_sq(fe51 h, const fe51 f)
|
||||
h[2] = g2;
|
||||
h[3] = g3;
|
||||
h[4] = g4;
|
||||
# endif
|
||||
# endif
|
||||
}
|
||||
|
||||
static void fe51_mul121666(fe51 h, fe51 f)
|
||||
{
|
||||
u128 h0 = f[0] * (u128)121666;
|
||||
u128 h1 = f[1] * (u128)121666;
|
||||
u128 h2 = f[2] * (u128)121666;
|
||||
u128 h3 = f[3] * (u128)121666;
|
||||
u128 h4 = f[4] * (u128)121666;
|
||||
uint64_t g0, g1, g2, g3, g4;
|
||||
|
||||
h3 += (uint64_t)(h2 >> 51); g2 = (uint64_t)h2 & MASK51;
|
||||
h1 += (uint64_t)(h0 >> 51); g0 = (uint64_t)h0 & MASK51;
|
||||
|
||||
h4 += (uint64_t)(h3 >> 51); g3 = (uint64_t)h3 & MASK51;
|
||||
g2 += (uint64_t)(h1 >> 51); g1 = (uint64_t)h1 & MASK51;
|
||||
|
||||
g0 += (uint64_t)(h4 >> 51) * 19; g4 = (uint64_t)h4 & MASK51;
|
||||
g3 += g2 >> 51; g2 &= MASK51;
|
||||
g1 += g0 >> 51; g0 &= MASK51;
|
||||
|
||||
h[0] = g0;
|
||||
h[1] = g1;
|
||||
h[2] = g2;
|
||||
h[3] = g3;
|
||||
h[4] = g4;
|
||||
}
|
||||
# endif
|
||||
|
||||
static void fe51_add(fe51 h, const fe51 f, const fe51 g)
|
||||
{
|
||||
h[0] = f[0] + g[0];
|
||||
@@ -258,8 +532,8 @@ static void fe51_sub(fe51 h, const fe51 f, const fe51 g)
|
||||
* Add 2*modulus to ensure that result remains positive
|
||||
* even if subtrahend is partially reduced.
|
||||
*/
|
||||
h[0] = (f[0] + 0xfffffffffffda) - g[0];
|
||||
h[1] = (f[1] + 0xffffffffffffe) - g[1];
|
||||
h[0] = (f[0] + 0xfffffffffffda) - g[0];
|
||||
h[1] = (f[1] + 0xffffffffffffe) - g[1];
|
||||
h[2] = (f[2] + 0xffffffffffffe) - g[2];
|
||||
h[3] = (f[3] + 0xffffffffffffe) - g[3];
|
||||
h[4] = (f[4] + 0xffffffffffffe) - g[4];
|
||||
@@ -396,32 +670,6 @@ static void fe51_invert(fe51 out, const fe51 z)
|
||||
fe51_mul(out, t1, t0);
|
||||
}
|
||||
|
||||
static void fe51_mul121666(fe51 h, fe51 f)
|
||||
{
|
||||
u128 h0 = f[0] * (u128)121666;
|
||||
u128 h1 = f[1] * (u128)121666;
|
||||
u128 h2 = f[2] * (u128)121666;
|
||||
u128 h3 = f[3] * (u128)121666;
|
||||
u128 h4 = f[4] * (u128)121666;
|
||||
uint64_t g0, g1, g2, g3, g4;
|
||||
|
||||
h3 += (uint64_t)(h2 >> 51); g2 = (uint64_t)h2 & MASK51;
|
||||
h1 += (uint64_t)(h0 >> 51); g0 = (uint64_t)h0 & MASK51;
|
||||
|
||||
h4 += (uint64_t)(h3 >> 51); g3 = (uint64_t)h3 & MASK51;
|
||||
g2 += (uint64_t)(h1 >> 51); g1 = (uint64_t)h1 & MASK51;
|
||||
|
||||
g0 += (uint64_t)(h4 >> 51) * 19; g4 = (uint64_t)h4 & MASK51;
|
||||
g3 += g2 >> 51; g2 &= MASK51;
|
||||
g1 += g0 >> 51; g0 &= MASK51;
|
||||
|
||||
h[0] = g0;
|
||||
h[1] = g1;
|
||||
h[2] = g2;
|
||||
h[3] = g3;
|
||||
h[4] = g4;
|
||||
}
|
||||
|
||||
/*
|
||||
* Duplicate of original x25519_scalar_mult_generic, but using
|
||||
* fe51_* subroutines.
|
||||
@@ -434,6 +682,13 @@ static void x25519_scalar_mult(uint8_t out[32], const uint8_t scalar[32],
|
||||
unsigned swap = 0;
|
||||
int pos;
|
||||
|
||||
# ifdef BASE_2_64_IMPLEMENTED
|
||||
if (x25519_fe64_eligible()) {
|
||||
x25519_scalar_mulx(out, scalar, point);
|
||||
return;
|
||||
}
|
||||
# endif
|
||||
|
||||
memcpy(e, scalar, 32);
|
||||
e[0] &= 0xf8;
|
||||
e[31] &= 0x7f;
|
||||
@@ -470,8 +725,6 @@ static void x25519_scalar_mult(uint8_t out[32], const uint8_t scalar[32],
|
||||
fe51_mul(z3, x1, z2);
|
||||
fe51_mul(z2, tmp1, tmp0);
|
||||
}
|
||||
fe51_cswap(x2, x3, swap);
|
||||
fe51_cswap(z2, z3, swap);
|
||||
|
||||
fe51_invert(z2, z2);
|
||||
fe51_mul(x2, x2, z2);
|
||||
@@ -554,16 +807,16 @@ static void fe_frombytes(fe h, const uint8_t *s) {
|
||||
carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & kTop38Bits;
|
||||
carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & kTop38Bits;
|
||||
|
||||
h[0] = h0;
|
||||
h[1] = h1;
|
||||
h[2] = h2;
|
||||
h[3] = h3;
|
||||
h[4] = h4;
|
||||
h[5] = h5;
|
||||
h[6] = h6;
|
||||
h[7] = h7;
|
||||
h[8] = h8;
|
||||
h[9] = h9;
|
||||
h[0] = (int32_t)h0;
|
||||
h[1] = (int32_t)h1;
|
||||
h[2] = (int32_t)h2;
|
||||
h[3] = (int32_t)h3;
|
||||
h[4] = (int32_t)h4;
|
||||
h[5] = (int32_t)h5;
|
||||
h[6] = (int32_t)h6;
|
||||
h[7] = (int32_t)h7;
|
||||
h[8] = (int32_t)h8;
|
||||
h[9] = (int32_t)h9;
|
||||
}
|
||||
|
||||
/* Preconditions:
|
||||
@@ -634,38 +887,38 @@ static void fe_tobytes(uint8_t *s, const fe h) {
|
||||
* evidently 2^255 h10-2^255 q = 0.
|
||||
* Goal: Output h0+...+2^230 h9. */
|
||||
|
||||
s[0] = h0 >> 0;
|
||||
s[1] = h0 >> 8;
|
||||
s[2] = h0 >> 16;
|
||||
s[3] = (h0 >> 24) | ((uint32_t)(h1) << 2);
|
||||
s[4] = h1 >> 6;
|
||||
s[5] = h1 >> 14;
|
||||
s[6] = (h1 >> 22) | ((uint32_t)(h2) << 3);
|
||||
s[7] = h2 >> 5;
|
||||
s[8] = h2 >> 13;
|
||||
s[9] = (h2 >> 21) | ((uint32_t)(h3) << 5);
|
||||
s[10] = h3 >> 3;
|
||||
s[11] = h3 >> 11;
|
||||
s[12] = (h3 >> 19) | ((uint32_t)(h4) << 6);
|
||||
s[13] = h4 >> 2;
|
||||
s[14] = h4 >> 10;
|
||||
s[15] = h4 >> 18;
|
||||
s[16] = h5 >> 0;
|
||||
s[17] = h5 >> 8;
|
||||
s[18] = h5 >> 16;
|
||||
s[19] = (h5 >> 24) | ((uint32_t)(h6) << 1);
|
||||
s[20] = h6 >> 7;
|
||||
s[21] = h6 >> 15;
|
||||
s[22] = (h6 >> 23) | ((uint32_t)(h7) << 3);
|
||||
s[23] = h7 >> 5;
|
||||
s[24] = h7 >> 13;
|
||||
s[25] = (h7 >> 21) | ((uint32_t)(h8) << 4);
|
||||
s[26] = h8 >> 4;
|
||||
s[27] = h8 >> 12;
|
||||
s[28] = (h8 >> 20) | ((uint32_t)(h9) << 6);
|
||||
s[29] = h9 >> 2;
|
||||
s[30] = h9 >> 10;
|
||||
s[31] = h9 >> 18;
|
||||
s[0] = (uint8_t)(h0 >> 0);
|
||||
s[1] = (uint8_t)(h0 >> 8);
|
||||
s[2] = (uint8_t)(h0 >> 16);
|
||||
s[3] = (uint8_t)((h0 >> 24) | ((uint32_t)(h1) << 2));
|
||||
s[4] = (uint8_t)(h1 >> 6);
|
||||
s[5] = (uint8_t)(h1 >> 14);
|
||||
s[6] = (uint8_t)((h1 >> 22) | ((uint32_t)(h2) << 3));
|
||||
s[7] = (uint8_t)(h2 >> 5);
|
||||
s[8] = (uint8_t)(h2 >> 13);
|
||||
s[9] = (uint8_t)((h2 >> 21) | ((uint32_t)(h3) << 5));
|
||||
s[10] = (uint8_t)(h3 >> 3);
|
||||
s[11] = (uint8_t)(h3 >> 11);
|
||||
s[12] = (uint8_t)((h3 >> 19) | ((uint32_t)(h4) << 6));
|
||||
s[13] = (uint8_t)(h4 >> 2);
|
||||
s[14] = (uint8_t)(h4 >> 10);
|
||||
s[15] = (uint8_t)(h4 >> 18);
|
||||
s[16] = (uint8_t)(h5 >> 0);
|
||||
s[17] = (uint8_t)(h5 >> 8);
|
||||
s[18] = (uint8_t)(h5 >> 16);
|
||||
s[19] = (uint8_t)((h5 >> 24) | ((uint32_t)(h6) << 1));
|
||||
s[20] = (uint8_t)(h6 >> 7);
|
||||
s[21] = (uint8_t)(h6 >> 15);
|
||||
s[22] = (uint8_t)((h6 >> 23) | ((uint32_t)(h7) << 3));
|
||||
s[23] = (uint8_t)(h7 >> 5);
|
||||
s[24] = (uint8_t)(h7 >> 13);
|
||||
s[25] = (uint8_t)((h7 >> 21) | ((uint32_t)(h8) << 4));
|
||||
s[26] = (uint8_t)(h8 >> 4);
|
||||
s[27] = (uint8_t)(h8 >> 12);
|
||||
s[28] = (uint8_t)((h8 >> 20) | ((uint32_t)(h9) << 6));
|
||||
s[29] = (uint8_t)(h9 >> 2);
|
||||
s[30] = (uint8_t)(h9 >> 10);
|
||||
s[31] = (uint8_t)(h9 >> 18);
|
||||
}
|
||||
|
||||
/* h = f */
|
||||
@@ -945,16 +1198,16 @@ static void fe_mul(fe h, const fe f, const fe g) {
|
||||
/* |h0| <= 2^25; from now on fits into int32 unchanged */
|
||||
/* |h1| <= 1.01*2^24 */
|
||||
|
||||
h[0] = h0;
|
||||
h[1] = h1;
|
||||
h[2] = h2;
|
||||
h[3] = h3;
|
||||
h[4] = h4;
|
||||
h[5] = h5;
|
||||
h[6] = h6;
|
||||
h[7] = h7;
|
||||
h[8] = h8;
|
||||
h[9] = h9;
|
||||
h[0] = (int32_t)h0;
|
||||
h[1] = (int32_t)h1;
|
||||
h[2] = (int32_t)h2;
|
||||
h[3] = (int32_t)h3;
|
||||
h[4] = (int32_t)h4;
|
||||
h[5] = (int32_t)h5;
|
||||
h[6] = (int32_t)h6;
|
||||
h[7] = (int32_t)h7;
|
||||
h[8] = (int32_t)h8;
|
||||
h[9] = (int32_t)h9;
|
||||
}
|
||||
|
||||
/* h = f * f
|
||||
@@ -1086,16 +1339,16 @@ static void fe_sq(fe h, const fe f) {
|
||||
|
||||
carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
|
||||
|
||||
h[0] = h0;
|
||||
h[1] = h1;
|
||||
h[2] = h2;
|
||||
h[3] = h3;
|
||||
h[4] = h4;
|
||||
h[5] = h5;
|
||||
h[6] = h6;
|
||||
h[7] = h7;
|
||||
h[8] = h8;
|
||||
h[9] = h9;
|
||||
h[0] = (int32_t)h0;
|
||||
h[1] = (int32_t)h1;
|
||||
h[2] = (int32_t)h2;
|
||||
h[3] = (int32_t)h3;
|
||||
h[4] = (int32_t)h4;
|
||||
h[5] = (int32_t)h5;
|
||||
h[6] = (int32_t)h6;
|
||||
h[7] = (int32_t)h7;
|
||||
h[8] = (int32_t)h8;
|
||||
h[9] = (int32_t)h9;
|
||||
}
|
||||
|
||||
static void fe_invert(fe out, const fe z) {
|
||||
@@ -1221,6 +1474,30 @@ static void fe_cmov(fe f, const fe g, unsigned b) {
|
||||
}
|
||||
}
|
||||
|
||||
/* return 0 if f == 0
|
||||
* return 1 if f != 0
|
||||
*
|
||||
* Preconditions:
|
||||
* |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. */
|
||||
static int fe_isnonzero(const fe f) {
|
||||
uint8_t s[32];
|
||||
static const uint8_t zero[32] = {0};
|
||||
fe_tobytes(s, f);
|
||||
|
||||
return CRYPTO_memcmp(s, zero, sizeof(zero)) != 0;
|
||||
}
|
||||
|
||||
/* return 1 if f is in {1,3,5,...,q-2}
|
||||
* return 0 if f is in {0,2,4,...,q-1}
|
||||
*
|
||||
* Preconditions:
|
||||
* |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. */
|
||||
static int fe_isnegative(const fe f) {
|
||||
uint8_t s[32];
|
||||
fe_tobytes(s, f);
|
||||
return s[0] & 1;
|
||||
}
|
||||
|
||||
/* h = 2 * f * f
|
||||
* Can overlap h with f.
|
||||
*
|
||||
@@ -1361,16 +1638,73 @@ static void fe_sq2(fe h, const fe f) {
|
||||
|
||||
carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
|
||||
|
||||
h[0] = h0;
|
||||
h[1] = h1;
|
||||
h[2] = h2;
|
||||
h[3] = h3;
|
||||
h[4] = h4;
|
||||
h[5] = h5;
|
||||
h[6] = h6;
|
||||
h[7] = h7;
|
||||
h[8] = h8;
|
||||
h[9] = h9;
|
||||
h[0] = (int32_t)h0;
|
||||
h[1] = (int32_t)h1;
|
||||
h[2] = (int32_t)h2;
|
||||
h[3] = (int32_t)h3;
|
||||
h[4] = (int32_t)h4;
|
||||
h[5] = (int32_t)h5;
|
||||
h[6] = (int32_t)h6;
|
||||
h[7] = (int32_t)h7;
|
||||
h[8] = (int32_t)h8;
|
||||
h[9] = (int32_t)h9;
|
||||
}
|
||||
|
||||
static void fe_pow22523(fe out, const fe z) {
|
||||
fe t0;
|
||||
fe t1;
|
||||
fe t2;
|
||||
int i;
|
||||
|
||||
fe_sq(t0, z);
|
||||
fe_sq(t1, t0);
|
||||
for (i = 1; i < 2; ++i) {
|
||||
fe_sq(t1, t1);
|
||||
}
|
||||
fe_mul(t1, z, t1);
|
||||
fe_mul(t0, t0, t1);
|
||||
fe_sq(t0, t0);
|
||||
fe_mul(t0, t1, t0);
|
||||
fe_sq(t1, t0);
|
||||
for (i = 1; i < 5; ++i) {
|
||||
fe_sq(t1, t1);
|
||||
}
|
||||
fe_mul(t0, t1, t0);
|
||||
fe_sq(t1, t0);
|
||||
for (i = 1; i < 10; ++i) {
|
||||
fe_sq(t1, t1);
|
||||
}
|
||||
fe_mul(t1, t1, t0);
|
||||
fe_sq(t2, t1);
|
||||
for (i = 1; i < 20; ++i) {
|
||||
fe_sq(t2, t2);
|
||||
}
|
||||
fe_mul(t1, t2, t1);
|
||||
fe_sq(t1, t1);
|
||||
for (i = 1; i < 10; ++i) {
|
||||
fe_sq(t1, t1);
|
||||
}
|
||||
fe_mul(t0, t1, t0);
|
||||
fe_sq(t1, t0);
|
||||
for (i = 1; i < 50; ++i) {
|
||||
fe_sq(t1, t1);
|
||||
}
|
||||
fe_mul(t1, t1, t0);
|
||||
fe_sq(t2, t1);
|
||||
for (i = 1; i < 100; ++i) {
|
||||
fe_sq(t2, t2);
|
||||
}
|
||||
fe_mul(t1, t2, t1);
|
||||
fe_sq(t1, t1);
|
||||
for (i = 1; i < 50; ++i) {
|
||||
fe_sq(t1, t1);
|
||||
}
|
||||
fe_mul(t0, t1, t0);
|
||||
fe_sq(t0, t0);
|
||||
for (i = 1; i < 2; ++i) {
|
||||
fe_sq(t0, t0);
|
||||
}
|
||||
fe_mul(out, t0, z);
|
||||
}
|
||||
|
||||
/* ge means group element.
|
||||
@@ -1418,6 +1752,85 @@ typedef struct {
|
||||
fe T2d;
|
||||
} ge_cached;
|
||||
|
||||
static void ge_tobytes(uint8_t *s, const ge_p2 *h) {
|
||||
fe recip;
|
||||
fe x;
|
||||
fe y;
|
||||
|
||||
fe_invert(recip, h->Z);
|
||||
fe_mul(x, h->X, recip);
|
||||
fe_mul(y, h->Y, recip);
|
||||
fe_tobytes(s, y);
|
||||
s[31] ^= fe_isnegative(x) << 7;
|
||||
}
|
||||
|
||||
static void ge_p3_tobytes(uint8_t *s, const ge_p3 *h) {
|
||||
fe recip;
|
||||
fe x;
|
||||
fe y;
|
||||
|
||||
fe_invert(recip, h->Z);
|
||||
fe_mul(x, h->X, recip);
|
||||
fe_mul(y, h->Y, recip);
|
||||
fe_tobytes(s, y);
|
||||
s[31] ^= fe_isnegative(x) << 7;
|
||||
}
|
||||
|
||||
static const fe d = {-10913610, 13857413, -15372611, 6949391, 114729,
|
||||
-8787816, -6275908, -3247719, -18696448, -12055116};
|
||||
|
||||
static const fe sqrtm1 = {-32595792, -7943725, 9377950, 3500415, 12389472,
|
||||
-272473, -25146209, -2005654, 326686, 11406482};
|
||||
|
||||
static int ge_frombytes_vartime(ge_p3 *h, const uint8_t *s) {
|
||||
fe u;
|
||||
fe v;
|
||||
fe v3;
|
||||
fe vxx;
|
||||
fe check;
|
||||
|
||||
fe_frombytes(h->Y, s);
|
||||
fe_1(h->Z);
|
||||
fe_sq(u, h->Y);
|
||||
fe_mul(v, u, d);
|
||||
fe_sub(u, u, h->Z); /* u = y^2-1 */
|
||||
fe_add(v, v, h->Z); /* v = dy^2+1 */
|
||||
|
||||
fe_sq(v3, v);
|
||||
fe_mul(v3, v3, v); /* v3 = v^3 */
|
||||
fe_sq(h->X, v3);
|
||||
fe_mul(h->X, h->X, v);
|
||||
fe_mul(h->X, h->X, u); /* x = uv^7 */
|
||||
|
||||
fe_pow22523(h->X, h->X); /* x = (uv^7)^((q-5)/8) */
|
||||
fe_mul(h->X, h->X, v3);
|
||||
fe_mul(h->X, h->X, u); /* x = uv^3(uv^7)^((q-5)/8) */
|
||||
|
||||
fe_sq(vxx, h->X);
|
||||
fe_mul(vxx, vxx, v);
|
||||
fe_sub(check, vxx, u); /* vx^2-u */
|
||||
if (fe_isnonzero(check)) {
|
||||
fe_add(check, vxx, u); /* vx^2+u */
|
||||
if (fe_isnonzero(check)) {
|
||||
return -1;
|
||||
}
|
||||
fe_mul(h->X, h->X, sqrtm1);
|
||||
}
|
||||
|
||||
if (fe_isnegative(h->X) != (s[31] >> 7)) {
|
||||
fe_neg(h->X, h->X);
|
||||
}
|
||||
|
||||
fe_mul(h->T, h->X, h->Y);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ge_p2_0(ge_p2 *h) {
|
||||
fe_0(h->X);
|
||||
fe_1(h->Y);
|
||||
fe_1(h->Z);
|
||||
}
|
||||
|
||||
static void ge_p3_0(ge_p3 *h) {
|
||||
fe_0(h->X);
|
||||
fe_1(h->Y);
|
||||
@@ -1438,6 +1851,17 @@ static void ge_p3_to_p2(ge_p2 *r, const ge_p3 *p) {
|
||||
fe_copy(r->Z, p->Z);
|
||||
}
|
||||
|
||||
static const fe d2 = {-21827239, -5839606, -30745221, 13898782, 229458,
|
||||
15978800, -12551817, -6495438, 29715968, 9444199};
|
||||
|
||||
/* r = p */
|
||||
static void ge_p3_to_cached(ge_cached *r, const ge_p3 *p) {
|
||||
fe_add(r->YplusX, p->Y, p->X);
|
||||
fe_sub(r->YminusX, p->Y, p->X);
|
||||
fe_copy(r->Z, p->Z);
|
||||
fe_mul(r->T2d, p->T, d2);
|
||||
}
|
||||
|
||||
/* r = p */
|
||||
static void ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p) {
|
||||
fe_mul(r->X, p->X, p->T);
|
||||
@@ -1491,6 +1915,56 @@ static void ge_madd(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) {
|
||||
fe_sub(r->T, t0, r->T);
|
||||
}
|
||||
|
||||
/* r = p - q */
|
||||
static void ge_msub(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) {
|
||||
fe t0;
|
||||
|
||||
fe_add(r->X, p->Y, p->X);
|
||||
fe_sub(r->Y, p->Y, p->X);
|
||||
fe_mul(r->Z, r->X, q->yminusx);
|
||||
fe_mul(r->Y, r->Y, q->yplusx);
|
||||
fe_mul(r->T, q->xy2d, p->T);
|
||||
fe_add(t0, p->Z, p->Z);
|
||||
fe_sub(r->X, r->Z, r->Y);
|
||||
fe_add(r->Y, r->Z, r->Y);
|
||||
fe_sub(r->Z, t0, r->T);
|
||||
fe_add(r->T, t0, r->T);
|
||||
}
|
||||
|
||||
/* r = p + q */
|
||||
static void ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) {
|
||||
fe t0;
|
||||
|
||||
fe_add(r->X, p->Y, p->X);
|
||||
fe_sub(r->Y, p->Y, p->X);
|
||||
fe_mul(r->Z, r->X, q->YplusX);
|
||||
fe_mul(r->Y, r->Y, q->YminusX);
|
||||
fe_mul(r->T, q->T2d, p->T);
|
||||
fe_mul(r->X, p->Z, q->Z);
|
||||
fe_add(t0, r->X, r->X);
|
||||
fe_sub(r->X, r->Z, r->Y);
|
||||
fe_add(r->Y, r->Z, r->Y);
|
||||
fe_add(r->Z, t0, r->T);
|
||||
fe_sub(r->T, t0, r->T);
|
||||
}
|
||||
|
||||
/* r = p - q */
|
||||
static void ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) {
|
||||
fe t0;
|
||||
|
||||
fe_add(r->X, p->Y, p->X);
|
||||
fe_sub(r->Y, p->Y, p->X);
|
||||
fe_mul(r->Z, r->X, q->YminusX);
|
||||
fe_mul(r->Y, r->Y, q->YplusX);
|
||||
fe_mul(r->T, q->T2d, p->T);
|
||||
fe_mul(r->X, p->Z, q->Z);
|
||||
fe_add(t0, r->X, r->X);
|
||||
fe_sub(r->X, r->Z, r->Y);
|
||||
fe_add(r->Y, r->Z, r->Y);
|
||||
fe_sub(r->Z, t0, r->T);
|
||||
fe_add(r->T, t0, r->T);
|
||||
}
|
||||
|
||||
static uint8_t equal(signed char b, signed char c) {
|
||||
uint8_t ub = b;
|
||||
uint8_t uc = c;
|
||||
@@ -3773,16 +4247,16 @@ static void fe_mul121666(fe h, fe f) {
|
||||
carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & kTop38Bits;
|
||||
carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & kTop38Bits;
|
||||
|
||||
h[0] = h0;
|
||||
h[1] = h1;
|
||||
h[2] = h2;
|
||||
h[3] = h3;
|
||||
h[4] = h4;
|
||||
h[5] = h5;
|
||||
h[6] = h6;
|
||||
h[7] = h7;
|
||||
h[8] = h8;
|
||||
h[9] = h9;
|
||||
h[0] = (int32_t)h0;
|
||||
h[1] = (int32_t)h1;
|
||||
h[2] = (int32_t)h2;
|
||||
h[3] = (int32_t)h3;
|
||||
h[4] = (int32_t)h4;
|
||||
h[5] = (int32_t)h5;
|
||||
h[6] = (int32_t)h6;
|
||||
h[7] = (int32_t)h7;
|
||||
h[8] = (int32_t)h8;
|
||||
h[9] = (int32_t)h9;
|
||||
}
|
||||
|
||||
static void x25519_scalar_mult_generic(uint8_t out[32],
|
||||
@@ -3828,8 +4302,6 @@ static void x25519_scalar_mult_generic(uint8_t out[32],
|
||||
fe_mul(z3, x1, z2);
|
||||
fe_mul(z2, tmp1, tmp0);
|
||||
}
|
||||
fe_cswap(x2, x3, swap);
|
||||
fe_cswap(z2, z3, swap);
|
||||
|
||||
fe_invert(z2, z2);
|
||||
fe_mul(x2, x2, z2);
|
||||
@@ -3844,6 +4316,1106 @@ static void x25519_scalar_mult(uint8_t out[32], const uint8_t scalar[32],
|
||||
}
|
||||
#endif
|
||||
|
||||
static void slide(signed char *r, const uint8_t *a) {
|
||||
int i;
|
||||
int b;
|
||||
int k;
|
||||
|
||||
for (i = 0; i < 256; ++i) {
|
||||
r[i] = 1 & (a[i >> 3] >> (i & 7));
|
||||
}
|
||||
|
||||
for (i = 0; i < 256; ++i) {
|
||||
if (r[i]) {
|
||||
for (b = 1; b <= 6 && i + b < 256; ++b) {
|
||||
if (r[i + b]) {
|
||||
if (r[i] + (r[i + b] << b) <= 15) {
|
||||
r[i] += r[i + b] << b;
|
||||
r[i + b] = 0;
|
||||
} else if (r[i] - (r[i + b] << b) >= -15) {
|
||||
r[i] -= r[i + b] << b;
|
||||
for (k = i + b; k < 256; ++k) {
|
||||
if (!r[k]) {
|
||||
r[k] = 1;
|
||||
break;
|
||||
}
|
||||
r[k] = 0;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const ge_precomp Bi[8] = {
|
||||
{
|
||||
{25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626,
|
||||
-11754271, -6079156, 2047605},
|
||||
{-12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692,
|
||||
5043384, 19500929, -15469378},
|
||||
{-8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919,
|
||||
11864899, -24514362, -4438546},
|
||||
},
|
||||
{
|
||||
{15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600,
|
||||
-14772189, 28944400, -1550024},
|
||||
{16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577,
|
||||
-11775962, 7689662, 11199574},
|
||||
{30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774,
|
||||
10017326, -17749093, -9920357},
|
||||
},
|
||||
{
|
||||
{10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885,
|
||||
14515107, -15438304, 10819380},
|
||||
{4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668,
|
||||
12483688, -12668491, 5581306},
|
||||
{19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350,
|
||||
13850243, -23678021, -15815942},
|
||||
},
|
||||
{
|
||||
{5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852,
|
||||
5230134, -23952439, -15175766},
|
||||
{-30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025,
|
||||
16520125, 30598449, 7715701},
|
||||
{28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660,
|
||||
1370708, 29794553, -1409300},
|
||||
},
|
||||
{
|
||||
{-22518993, -6692182, 14201702, -8745502, -23510406, 8844726, 18474211,
|
||||
-1361450, -13062696, 13821877},
|
||||
{-6455177, -7839871, 3374702, -4740862, -27098617, -10571707, 31655028,
|
||||
-7212327, 18853322, -14220951},
|
||||
{4566830, -12963868, -28974889, -12240689, -7602672, -2830569, -8514358,
|
||||
-10431137, 2207753, -3209784},
|
||||
},
|
||||
{
|
||||
{-25154831, -4185821, 29681144, 7868801, -6854661, -9423865, -12437364,
|
||||
-663000, -31111463, -16132436},
|
||||
{25576264, -2703214, 7349804, -11814844, 16472782, 9300885, 3844789,
|
||||
15725684, 171356, 6466918},
|
||||
{23103977, 13316479, 9739013, -16149481, 817875, -15038942, 8965339,
|
||||
-14088058, -30714912, 16193877},
|
||||
},
|
||||
{
|
||||
{-33521811, 3180713, -2394130, 14003687, -16903474, -16270840, 17238398,
|
||||
4729455, -18074513, 9256800},
|
||||
{-25182317, -4174131, 32336398, 5036987, -21236817, 11360617, 22616405,
|
||||
9761698, -19827198, 630305},
|
||||
{-13720693, 2639453, -24237460, -7406481, 9494427, -5774029, -6554551,
|
||||
-15960994, -2449256, -14291300},
|
||||
},
|
||||
{
|
||||
{-3151181, -5046075, 9282714, 6866145, -31907062, -863023, -18940575,
|
||||
15033784, 25105118, -7894876},
|
||||
{-24326370, 15950226, -31801215, -14592823, -11662737, -5090925,
|
||||
1573892, -2625887, 2198790, -15804619},
|
||||
{-3099351, 10324967, -2241613, 7453183, -5446979, -2735503, -13812022,
|
||||
-16236442, -32461234, -12290683},
|
||||
},
|
||||
};
|
||||
|
||||
/* r = a * A + b * B
|
||||
* where a = a[0]+256*a[1]+...+256^31 a[31].
|
||||
* and b = b[0]+256*b[1]+...+256^31 b[31].
|
||||
* B is the Ed25519 base point (x,4/5) with x positive. */
|
||||
static void ge_double_scalarmult_vartime(ge_p2 *r, const uint8_t *a,
|
||||
const ge_p3 *A, const uint8_t *b) {
|
||||
signed char aslide[256];
|
||||
signed char bslide[256];
|
||||
ge_cached Ai[8]; /* A,3A,5A,7A,9A,11A,13A,15A */
|
||||
ge_p1p1 t;
|
||||
ge_p3 u;
|
||||
ge_p3 A2;
|
||||
int i;
|
||||
|
||||
slide(aslide, a);
|
||||
slide(bslide, b);
|
||||
|
||||
ge_p3_to_cached(&Ai[0], A);
|
||||
ge_p3_dbl(&t, A);
|
||||
ge_p1p1_to_p3(&A2, &t);
|
||||
ge_add(&t, &A2, &Ai[0]);
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_p3_to_cached(&Ai[1], &u);
|
||||
ge_add(&t, &A2, &Ai[1]);
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_p3_to_cached(&Ai[2], &u);
|
||||
ge_add(&t, &A2, &Ai[2]);
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_p3_to_cached(&Ai[3], &u);
|
||||
ge_add(&t, &A2, &Ai[3]);
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_p3_to_cached(&Ai[4], &u);
|
||||
ge_add(&t, &A2, &Ai[4]);
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_p3_to_cached(&Ai[5], &u);
|
||||
ge_add(&t, &A2, &Ai[5]);
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_p3_to_cached(&Ai[6], &u);
|
||||
ge_add(&t, &A2, &Ai[6]);
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_p3_to_cached(&Ai[7], &u);
|
||||
|
||||
ge_p2_0(r);
|
||||
|
||||
for (i = 255; i >= 0; --i) {
|
||||
if (aslide[i] || bslide[i]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (; i >= 0; --i) {
|
||||
ge_p2_dbl(&t, r);
|
||||
|
||||
if (aslide[i] > 0) {
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_add(&t, &u, &Ai[aslide[i] / 2]);
|
||||
} else if (aslide[i] < 0) {
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_sub(&t, &u, &Ai[(-aslide[i]) / 2]);
|
||||
}
|
||||
|
||||
if (bslide[i] > 0) {
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_madd(&t, &u, &Bi[bslide[i] / 2]);
|
||||
} else if (bslide[i] < 0) {
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_msub(&t, &u, &Bi[(-bslide[i]) / 2]);
|
||||
}
|
||||
|
||||
ge_p1p1_to_p2(r, &t);
|
||||
}
|
||||
}
|
||||
|
||||
/* The set of scalars is \Z/l
|
||||
* where l = 2^252 + 27742317777372353535851937790883648493. */
|
||||
|
||||
/* Input:
|
||||
* s[0]+256*s[1]+...+256^63*s[63] = s
|
||||
*
|
||||
* Output:
|
||||
* s[0]+256*s[1]+...+256^31*s[31] = s mod l
|
||||
* where l = 2^252 + 27742317777372353535851937790883648493.
|
||||
* Overwrites s in place. */
|
||||
static void x25519_sc_reduce(uint8_t *s) {
|
||||
int64_t s0 = 2097151 & load_3(s);
|
||||
int64_t s1 = 2097151 & (load_4(s + 2) >> 5);
|
||||
int64_t s2 = 2097151 & (load_3(s + 5) >> 2);
|
||||
int64_t s3 = 2097151 & (load_4(s + 7) >> 7);
|
||||
int64_t s4 = 2097151 & (load_4(s + 10) >> 4);
|
||||
int64_t s5 = 2097151 & (load_3(s + 13) >> 1);
|
||||
int64_t s6 = 2097151 & (load_4(s + 15) >> 6);
|
||||
int64_t s7 = 2097151 & (load_3(s + 18) >> 3);
|
||||
int64_t s8 = 2097151 & load_3(s + 21);
|
||||
int64_t s9 = 2097151 & (load_4(s + 23) >> 5);
|
||||
int64_t s10 = 2097151 & (load_3(s + 26) >> 2);
|
||||
int64_t s11 = 2097151 & (load_4(s + 28) >> 7);
|
||||
int64_t s12 = 2097151 & (load_4(s + 31) >> 4);
|
||||
int64_t s13 = 2097151 & (load_3(s + 34) >> 1);
|
||||
int64_t s14 = 2097151 & (load_4(s + 36) >> 6);
|
||||
int64_t s15 = 2097151 & (load_3(s + 39) >> 3);
|
||||
int64_t s16 = 2097151 & load_3(s + 42);
|
||||
int64_t s17 = 2097151 & (load_4(s + 44) >> 5);
|
||||
int64_t s18 = 2097151 & (load_3(s + 47) >> 2);
|
||||
int64_t s19 = 2097151 & (load_4(s + 49) >> 7);
|
||||
int64_t s20 = 2097151 & (load_4(s + 52) >> 4);
|
||||
int64_t s21 = 2097151 & (load_3(s + 55) >> 1);
|
||||
int64_t s22 = 2097151 & (load_4(s + 57) >> 6);
|
||||
int64_t s23 = (load_4(s + 60) >> 3);
|
||||
int64_t carry0;
|
||||
int64_t carry1;
|
||||
int64_t carry2;
|
||||
int64_t carry3;
|
||||
int64_t carry4;
|
||||
int64_t carry5;
|
||||
int64_t carry6;
|
||||
int64_t carry7;
|
||||
int64_t carry8;
|
||||
int64_t carry9;
|
||||
int64_t carry10;
|
||||
int64_t carry11;
|
||||
int64_t carry12;
|
||||
int64_t carry13;
|
||||
int64_t carry14;
|
||||
int64_t carry15;
|
||||
int64_t carry16;
|
||||
|
||||
s11 += s23 * 666643;
|
||||
s12 += s23 * 470296;
|
||||
s13 += s23 * 654183;
|
||||
s14 -= s23 * 997805;
|
||||
s15 += s23 * 136657;
|
||||
s16 -= s23 * 683901;
|
||||
s23 = 0;
|
||||
|
||||
s10 += s22 * 666643;
|
||||
s11 += s22 * 470296;
|
||||
s12 += s22 * 654183;
|
||||
s13 -= s22 * 997805;
|
||||
s14 += s22 * 136657;
|
||||
s15 -= s22 * 683901;
|
||||
s22 = 0;
|
||||
|
||||
s9 += s21 * 666643;
|
||||
s10 += s21 * 470296;
|
||||
s11 += s21 * 654183;
|
||||
s12 -= s21 * 997805;
|
||||
s13 += s21 * 136657;
|
||||
s14 -= s21 * 683901;
|
||||
s21 = 0;
|
||||
|
||||
s8 += s20 * 666643;
|
||||
s9 += s20 * 470296;
|
||||
s10 += s20 * 654183;
|
||||
s11 -= s20 * 997805;
|
||||
s12 += s20 * 136657;
|
||||
s13 -= s20 * 683901;
|
||||
s20 = 0;
|
||||
|
||||
s7 += s19 * 666643;
|
||||
s8 += s19 * 470296;
|
||||
s9 += s19 * 654183;
|
||||
s10 -= s19 * 997805;
|
||||
s11 += s19 * 136657;
|
||||
s12 -= s19 * 683901;
|
||||
s19 = 0;
|
||||
|
||||
s6 += s18 * 666643;
|
||||
s7 += s18 * 470296;
|
||||
s8 += s18 * 654183;
|
||||
s9 -= s18 * 997805;
|
||||
s10 += s18 * 136657;
|
||||
s11 -= s18 * 683901;
|
||||
s18 = 0;
|
||||
|
||||
carry6 = (s6 + (1 << 20)) >> 21;
|
||||
s7 += carry6;
|
||||
s6 -= carry6 * (1 << 21);
|
||||
carry8 = (s8 + (1 << 20)) >> 21;
|
||||
s9 += carry8;
|
||||
s8 -= carry8 * (1 << 21);
|
||||
carry10 = (s10 + (1 << 20)) >> 21;
|
||||
s11 += carry10;
|
||||
s10 -= carry10 * (1 << 21);
|
||||
carry12 = (s12 + (1 << 20)) >> 21;
|
||||
s13 += carry12;
|
||||
s12 -= carry12 * (1 << 21);
|
||||
carry14 = (s14 + (1 << 20)) >> 21;
|
||||
s15 += carry14;
|
||||
s14 -= carry14 * (1 << 21);
|
||||
carry16 = (s16 + (1 << 20)) >> 21;
|
||||
s17 += carry16;
|
||||
s16 -= carry16 * (1 << 21);
|
||||
|
||||
carry7 = (s7 + (1 << 20)) >> 21;
|
||||
s8 += carry7;
|
||||
s7 -= carry7 * (1 << 21);
|
||||
carry9 = (s9 + (1 << 20)) >> 21;
|
||||
s10 += carry9;
|
||||
s9 -= carry9 * (1 << 21);
|
||||
carry11 = (s11 + (1 << 20)) >> 21;
|
||||
s12 += carry11;
|
||||
s11 -= carry11 * (1 << 21);
|
||||
carry13 = (s13 + (1 << 20)) >> 21;
|
||||
s14 += carry13;
|
||||
s13 -= carry13 * (1 << 21);
|
||||
carry15 = (s15 + (1 << 20)) >> 21;
|
||||
s16 += carry15;
|
||||
s15 -= carry15 * (1 << 21);
|
||||
|
||||
s5 += s17 * 666643;
|
||||
s6 += s17 * 470296;
|
||||
s7 += s17 * 654183;
|
||||
s8 -= s17 * 997805;
|
||||
s9 += s17 * 136657;
|
||||
s10 -= s17 * 683901;
|
||||
s17 = 0;
|
||||
|
||||
s4 += s16 * 666643;
|
||||
s5 += s16 * 470296;
|
||||
s6 += s16 * 654183;
|
||||
s7 -= s16 * 997805;
|
||||
s8 += s16 * 136657;
|
||||
s9 -= s16 * 683901;
|
||||
s16 = 0;
|
||||
|
||||
s3 += s15 * 666643;
|
||||
s4 += s15 * 470296;
|
||||
s5 += s15 * 654183;
|
||||
s6 -= s15 * 997805;
|
||||
s7 += s15 * 136657;
|
||||
s8 -= s15 * 683901;
|
||||
s15 = 0;
|
||||
|
||||
s2 += s14 * 666643;
|
||||
s3 += s14 * 470296;
|
||||
s4 += s14 * 654183;
|
||||
s5 -= s14 * 997805;
|
||||
s6 += s14 * 136657;
|
||||
s7 -= s14 * 683901;
|
||||
s14 = 0;
|
||||
|
||||
s1 += s13 * 666643;
|
||||
s2 += s13 * 470296;
|
||||
s3 += s13 * 654183;
|
||||
s4 -= s13 * 997805;
|
||||
s5 += s13 * 136657;
|
||||
s6 -= s13 * 683901;
|
||||
s13 = 0;
|
||||
|
||||
s0 += s12 * 666643;
|
||||
s1 += s12 * 470296;
|
||||
s2 += s12 * 654183;
|
||||
s3 -= s12 * 997805;
|
||||
s4 += s12 * 136657;
|
||||
s5 -= s12 * 683901;
|
||||
s12 = 0;
|
||||
|
||||
carry0 = (s0 + (1 << 20)) >> 21;
|
||||
s1 += carry0;
|
||||
s0 -= carry0 * (1 << 21);
|
||||
carry2 = (s2 + (1 << 20)) >> 21;
|
||||
s3 += carry2;
|
||||
s2 -= carry2 * (1 << 21);
|
||||
carry4 = (s4 + (1 << 20)) >> 21;
|
||||
s5 += carry4;
|
||||
s4 -= carry4 * (1 << 21);
|
||||
carry6 = (s6 + (1 << 20)) >> 21;
|
||||
s7 += carry6;
|
||||
s6 -= carry6 * (1 << 21);
|
||||
carry8 = (s8 + (1 << 20)) >> 21;
|
||||
s9 += carry8;
|
||||
s8 -= carry8 * (1 << 21);
|
||||
carry10 = (s10 + (1 << 20)) >> 21;
|
||||
s11 += carry10;
|
||||
s10 -= carry10 * (1 << 21);
|
||||
|
||||
carry1 = (s1 + (1 << 20)) >> 21;
|
||||
s2 += carry1;
|
||||
s1 -= carry1 * (1 << 21);
|
||||
carry3 = (s3 + (1 << 20)) >> 21;
|
||||
s4 += carry3;
|
||||
s3 -= carry3 * (1 << 21);
|
||||
carry5 = (s5 + (1 << 20)) >> 21;
|
||||
s6 += carry5;
|
||||
s5 -= carry5 * (1 << 21);
|
||||
carry7 = (s7 + (1 << 20)) >> 21;
|
||||
s8 += carry7;
|
||||
s7 -= carry7 * (1 << 21);
|
||||
carry9 = (s9 + (1 << 20)) >> 21;
|
||||
s10 += carry9;
|
||||
s9 -= carry9 * (1 << 21);
|
||||
carry11 = (s11 + (1 << 20)) >> 21;
|
||||
s12 += carry11;
|
||||
s11 -= carry11 * (1 << 21);
|
||||
|
||||
s0 += s12 * 666643;
|
||||
s1 += s12 * 470296;
|
||||
s2 += s12 * 654183;
|
||||
s3 -= s12 * 997805;
|
||||
s4 += s12 * 136657;
|
||||
s5 -= s12 * 683901;
|
||||
s12 = 0;
|
||||
|
||||
carry0 = s0 >> 21;
|
||||
s1 += carry0;
|
||||
s0 -= carry0 * (1 << 21);
|
||||
carry1 = s1 >> 21;
|
||||
s2 += carry1;
|
||||
s1 -= carry1 * (1 << 21);
|
||||
carry2 = s2 >> 21;
|
||||
s3 += carry2;
|
||||
s2 -= carry2 * (1 << 21);
|
||||
carry3 = s3 >> 21;
|
||||
s4 += carry3;
|
||||
s3 -= carry3 * (1 << 21);
|
||||
carry4 = s4 >> 21;
|
||||
s5 += carry4;
|
||||
s4 -= carry4 * (1 << 21);
|
||||
carry5 = s5 >> 21;
|
||||
s6 += carry5;
|
||||
s5 -= carry5 * (1 << 21);
|
||||
carry6 = s6 >> 21;
|
||||
s7 += carry6;
|
||||
s6 -= carry6 * (1 << 21);
|
||||
carry7 = s7 >> 21;
|
||||
s8 += carry7;
|
||||
s7 -= carry7 * (1 << 21);
|
||||
carry8 = s8 >> 21;
|
||||
s9 += carry8;
|
||||
s8 -= carry8 * (1 << 21);
|
||||
carry9 = s9 >> 21;
|
||||
s10 += carry9;
|
||||
s9 -= carry9 * (1 << 21);
|
||||
carry10 = s10 >> 21;
|
||||
s11 += carry10;
|
||||
s10 -= carry10 * (1 << 21);
|
||||
carry11 = s11 >> 21;
|
||||
s12 += carry11;
|
||||
s11 -= carry11 * (1 << 21);
|
||||
|
||||
s0 += s12 * 666643;
|
||||
s1 += s12 * 470296;
|
||||
s2 += s12 * 654183;
|
||||
s3 -= s12 * 997805;
|
||||
s4 += s12 * 136657;
|
||||
s5 -= s12 * 683901;
|
||||
s12 = 0;
|
||||
|
||||
carry0 = s0 >> 21;
|
||||
s1 += carry0;
|
||||
s0 -= carry0 * (1 << 21);
|
||||
carry1 = s1 >> 21;
|
||||
s2 += carry1;
|
||||
s1 -= carry1 * (1 << 21);
|
||||
carry2 = s2 >> 21;
|
||||
s3 += carry2;
|
||||
s2 -= carry2 * (1 << 21);
|
||||
carry3 = s3 >> 21;
|
||||
s4 += carry3;
|
||||
s3 -= carry3 * (1 << 21);
|
||||
carry4 = s4 >> 21;
|
||||
s5 += carry4;
|
||||
s4 -= carry4 * (1 << 21);
|
||||
carry5 = s5 >> 21;
|
||||
s6 += carry5;
|
||||
s5 -= carry5 * (1 << 21);
|
||||
carry6 = s6 >> 21;
|
||||
s7 += carry6;
|
||||
s6 -= carry6 * (1 << 21);
|
||||
carry7 = s7 >> 21;
|
||||
s8 += carry7;
|
||||
s7 -= carry7 * (1 << 21);
|
||||
carry8 = s8 >> 21;
|
||||
s9 += carry8;
|
||||
s8 -= carry8 * (1 << 21);
|
||||
carry9 = s9 >> 21;
|
||||
s10 += carry9;
|
||||
s9 -= carry9 * (1 << 21);
|
||||
carry10 = s10 >> 21;
|
||||
s11 += carry10;
|
||||
s10 -= carry10 * (1 << 21);
|
||||
|
||||
s[0] = (uint8_t)(s0 >> 0);
|
||||
s[1] = (uint8_t)(s0 >> 8);
|
||||
s[2] = (uint8_t)((s0 >> 16) | (s1 << 5));
|
||||
s[3] = (uint8_t)(s1 >> 3);
|
||||
s[4] = (uint8_t)(s1 >> 11);
|
||||
s[5] = (uint8_t)((s1 >> 19) | (s2 << 2));
|
||||
s[6] = (uint8_t)(s2 >> 6);
|
||||
s[7] = (uint8_t)((s2 >> 14) | (s3 << 7));
|
||||
s[8] = (uint8_t)(s3 >> 1);
|
||||
s[9] = (uint8_t)(s3 >> 9);
|
||||
s[10] = (uint8_t)((s3 >> 17) | (s4 << 4));
|
||||
s[11] = (uint8_t)(s4 >> 4);
|
||||
s[12] = (uint8_t)(s4 >> 12);
|
||||
s[13] = (uint8_t)((s4 >> 20) | (s5 << 1));
|
||||
s[14] = (uint8_t)(s5 >> 7);
|
||||
s[15] = (uint8_t)((s5 >> 15) | (s6 << 6));
|
||||
s[16] = (uint8_t)(s6 >> 2);
|
||||
s[17] = (uint8_t)(s6 >> 10);
|
||||
s[18] = (uint8_t)((s6 >> 18) | (s7 << 3));
|
||||
s[19] = (uint8_t)(s7 >> 5);
|
||||
s[20] = (uint8_t)(s7 >> 13);
|
||||
s[21] = (uint8_t)(s8 >> 0);
|
||||
s[22] = (uint8_t)(s8 >> 8);
|
||||
s[23] = (uint8_t)((s8 >> 16) | (s9 << 5));
|
||||
s[24] = (uint8_t)(s9 >> 3);
|
||||
s[25] = (uint8_t)(s9 >> 11);
|
||||
s[26] = (uint8_t)((s9 >> 19) | (s10 << 2));
|
||||
s[27] = (uint8_t)(s10 >> 6);
|
||||
s[28] = (uint8_t)((s10 >> 14) | (s11 << 7));
|
||||
s[29] = (uint8_t)(s11 >> 1);
|
||||
s[30] = (uint8_t)(s11 >> 9);
|
||||
s[31] = (uint8_t)(s11 >> 17);
|
||||
}
|
||||
|
||||
/* Input:
|
||||
* a[0]+256*a[1]+...+256^31*a[31] = a
|
||||
* b[0]+256*b[1]+...+256^31*b[31] = b
|
||||
* c[0]+256*c[1]+...+256^31*c[31] = c
|
||||
*
|
||||
* Output:
|
||||
* s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l
|
||||
* where l = 2^252 + 27742317777372353535851937790883648493. */
|
||||
static void sc_muladd(uint8_t *s, const uint8_t *a, const uint8_t *b,
|
||||
const uint8_t *c) {
|
||||
int64_t a0 = 2097151 & load_3(a);
|
||||
int64_t a1 = 2097151 & (load_4(a + 2) >> 5);
|
||||
int64_t a2 = 2097151 & (load_3(a + 5) >> 2);
|
||||
int64_t a3 = 2097151 & (load_4(a + 7) >> 7);
|
||||
int64_t a4 = 2097151 & (load_4(a + 10) >> 4);
|
||||
int64_t a5 = 2097151 & (load_3(a + 13) >> 1);
|
||||
int64_t a6 = 2097151 & (load_4(a + 15) >> 6);
|
||||
int64_t a7 = 2097151 & (load_3(a + 18) >> 3);
|
||||
int64_t a8 = 2097151 & load_3(a + 21);
|
||||
int64_t a9 = 2097151 & (load_4(a + 23) >> 5);
|
||||
int64_t a10 = 2097151 & (load_3(a + 26) >> 2);
|
||||
int64_t a11 = (load_4(a + 28) >> 7);
|
||||
int64_t b0 = 2097151 & load_3(b);
|
||||
int64_t b1 = 2097151 & (load_4(b + 2) >> 5);
|
||||
int64_t b2 = 2097151 & (load_3(b + 5) >> 2);
|
||||
int64_t b3 = 2097151 & (load_4(b + 7) >> 7);
|
||||
int64_t b4 = 2097151 & (load_4(b + 10) >> 4);
|
||||
int64_t b5 = 2097151 & (load_3(b + 13) >> 1);
|
||||
int64_t b6 = 2097151 & (load_4(b + 15) >> 6);
|
||||
int64_t b7 = 2097151 & (load_3(b + 18) >> 3);
|
||||
int64_t b8 = 2097151 & load_3(b + 21);
|
||||
int64_t b9 = 2097151 & (load_4(b + 23) >> 5);
|
||||
int64_t b10 = 2097151 & (load_3(b + 26) >> 2);
|
||||
int64_t b11 = (load_4(b + 28) >> 7);
|
||||
int64_t c0 = 2097151 & load_3(c);
|
||||
int64_t c1 = 2097151 & (load_4(c + 2) >> 5);
|
||||
int64_t c2 = 2097151 & (load_3(c + 5) >> 2);
|
||||
int64_t c3 = 2097151 & (load_4(c + 7) >> 7);
|
||||
int64_t c4 = 2097151 & (load_4(c + 10) >> 4);
|
||||
int64_t c5 = 2097151 & (load_3(c + 13) >> 1);
|
||||
int64_t c6 = 2097151 & (load_4(c + 15) >> 6);
|
||||
int64_t c7 = 2097151 & (load_3(c + 18) >> 3);
|
||||
int64_t c8 = 2097151 & load_3(c + 21);
|
||||
int64_t c9 = 2097151 & (load_4(c + 23) >> 5);
|
||||
int64_t c10 = 2097151 & (load_3(c + 26) >> 2);
|
||||
int64_t c11 = (load_4(c + 28) >> 7);
|
||||
int64_t s0;
|
||||
int64_t s1;
|
||||
int64_t s2;
|
||||
int64_t s3;
|
||||
int64_t s4;
|
||||
int64_t s5;
|
||||
int64_t s6;
|
||||
int64_t s7;
|
||||
int64_t s8;
|
||||
int64_t s9;
|
||||
int64_t s10;
|
||||
int64_t s11;
|
||||
int64_t s12;
|
||||
int64_t s13;
|
||||
int64_t s14;
|
||||
int64_t s15;
|
||||
int64_t s16;
|
||||
int64_t s17;
|
||||
int64_t s18;
|
||||
int64_t s19;
|
||||
int64_t s20;
|
||||
int64_t s21;
|
||||
int64_t s22;
|
||||
int64_t s23;
|
||||
int64_t carry0;
|
||||
int64_t carry1;
|
||||
int64_t carry2;
|
||||
int64_t carry3;
|
||||
int64_t carry4;
|
||||
int64_t carry5;
|
||||
int64_t carry6;
|
||||
int64_t carry7;
|
||||
int64_t carry8;
|
||||
int64_t carry9;
|
||||
int64_t carry10;
|
||||
int64_t carry11;
|
||||
int64_t carry12;
|
||||
int64_t carry13;
|
||||
int64_t carry14;
|
||||
int64_t carry15;
|
||||
int64_t carry16;
|
||||
int64_t carry17;
|
||||
int64_t carry18;
|
||||
int64_t carry19;
|
||||
int64_t carry20;
|
||||
int64_t carry21;
|
||||
int64_t carry22;
|
||||
|
||||
s0 = c0 + a0 * b0;
|
||||
s1 = c1 + a0 * b1 + a1 * b0;
|
||||
s2 = c2 + a0 * b2 + a1 * b1 + a2 * b0;
|
||||
s3 = c3 + a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0;
|
||||
s4 = c4 + a0 * b4 + a1 * b3 + a2 * b2 + a3 * b1 + a4 * b0;
|
||||
s5 = c5 + a0 * b5 + a1 * b4 + a2 * b3 + a3 * b2 + a4 * b1 + a5 * b0;
|
||||
s6 = c6 + a0 * b6 + a1 * b5 + a2 * b4 + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0;
|
||||
s7 = c7 + a0 * b7 + a1 * b6 + a2 * b5 + a3 * b4 + a4 * b3 + a5 * b2 +
|
||||
a6 * b1 + a7 * b0;
|
||||
s8 = c8 + a0 * b8 + a1 * b7 + a2 * b6 + a3 * b5 + a4 * b4 + a5 * b3 +
|
||||
a6 * b2 + a7 * b1 + a8 * b0;
|
||||
s9 = c9 + a0 * b9 + a1 * b8 + a2 * b7 + a3 * b6 + a4 * b5 + a5 * b4 +
|
||||
a6 * b3 + a7 * b2 + a8 * b1 + a9 * b0;
|
||||
s10 = c10 + a0 * b10 + a1 * b9 + a2 * b8 + a3 * b7 + a4 * b6 + a5 * b5 +
|
||||
a6 * b4 + a7 * b3 + a8 * b2 + a9 * b1 + a10 * b0;
|
||||
s11 = c11 + a0 * b11 + a1 * b10 + a2 * b9 + a3 * b8 + a4 * b7 + a5 * b6 +
|
||||
a6 * b5 + a7 * b4 + a8 * b3 + a9 * b2 + a10 * b1 + a11 * b0;
|
||||
s12 = a1 * b11 + a2 * b10 + a3 * b9 + a4 * b8 + a5 * b7 + a6 * b6 + a7 * b5 +
|
||||
a8 * b4 + a9 * b3 + a10 * b2 + a11 * b1;
|
||||
s13 = a2 * b11 + a3 * b10 + a4 * b9 + a5 * b8 + a6 * b7 + a7 * b6 + a8 * b5 +
|
||||
a9 * b4 + a10 * b3 + a11 * b2;
|
||||
s14 = a3 * b11 + a4 * b10 + a5 * b9 + a6 * b8 + a7 * b7 + a8 * b6 + a9 * b5 +
|
||||
a10 * b4 + a11 * b3;
|
||||
s15 = a4 * b11 + a5 * b10 + a6 * b9 + a7 * b8 + a8 * b7 + a9 * b6 + a10 * b5 +
|
||||
a11 * b4;
|
||||
s16 = a5 * b11 + a6 * b10 + a7 * b9 + a8 * b8 + a9 * b7 + a10 * b6 + a11 * b5;
|
||||
s17 = a6 * b11 + a7 * b10 + a8 * b9 + a9 * b8 + a10 * b7 + a11 * b6;
|
||||
s18 = a7 * b11 + a8 * b10 + a9 * b9 + a10 * b8 + a11 * b7;
|
||||
s19 = a8 * b11 + a9 * b10 + a10 * b9 + a11 * b8;
|
||||
s20 = a9 * b11 + a10 * b10 + a11 * b9;
|
||||
s21 = a10 * b11 + a11 * b10;
|
||||
s22 = a11 * b11;
|
||||
s23 = 0;
|
||||
|
||||
carry0 = (s0 + (1 << 20)) >> 21;
|
||||
s1 += carry0;
|
||||
s0 -= carry0 * (1 << 21);
|
||||
carry2 = (s2 + (1 << 20)) >> 21;
|
||||
s3 += carry2;
|
||||
s2 -= carry2 * (1 << 21);
|
||||
carry4 = (s4 + (1 << 20)) >> 21;
|
||||
s5 += carry4;
|
||||
s4 -= carry4 * (1 << 21);
|
||||
carry6 = (s6 + (1 << 20)) >> 21;
|
||||
s7 += carry6;
|
||||
s6 -= carry6 * (1 << 21);
|
||||
carry8 = (s8 + (1 << 20)) >> 21;
|
||||
s9 += carry8;
|
||||
s8 -= carry8 * (1 << 21);
|
||||
carry10 = (s10 + (1 << 20)) >> 21;
|
||||
s11 += carry10;
|
||||
s10 -= carry10 * (1 << 21);
|
||||
carry12 = (s12 + (1 << 20)) >> 21;
|
||||
s13 += carry12;
|
||||
s12 -= carry12 * (1 << 21);
|
||||
carry14 = (s14 + (1 << 20)) >> 21;
|
||||
s15 += carry14;
|
||||
s14 -= carry14 * (1 << 21);
|
||||
carry16 = (s16 + (1 << 20)) >> 21;
|
||||
s17 += carry16;
|
||||
s16 -= carry16 * (1 << 21);
|
||||
carry18 = (s18 + (1 << 20)) >> 21;
|
||||
s19 += carry18;
|
||||
s18 -= carry18 * (1 << 21);
|
||||
carry20 = (s20 + (1 << 20)) >> 21;
|
||||
s21 += carry20;
|
||||
s20 -= carry20 * (1 << 21);
|
||||
carry22 = (s22 + (1 << 20)) >> 21;
|
||||
s23 += carry22;
|
||||
s22 -= carry22 * (1 << 21);
|
||||
|
||||
carry1 = (s1 + (1 << 20)) >> 21;
|
||||
s2 += carry1;
|
||||
s1 -= carry1 * (1 << 21);
|
||||
carry3 = (s3 + (1 << 20)) >> 21;
|
||||
s4 += carry3;
|
||||
s3 -= carry3 * (1 << 21);
|
||||
carry5 = (s5 + (1 << 20)) >> 21;
|
||||
s6 += carry5;
|
||||
s5 -= carry5 * (1 << 21);
|
||||
carry7 = (s7 + (1 << 20)) >> 21;
|
||||
s8 += carry7;
|
||||
s7 -= carry7 * (1 << 21);
|
||||
carry9 = (s9 + (1 << 20)) >> 21;
|
||||
s10 += carry9;
|
||||
s9 -= carry9 * (1 << 21);
|
||||
carry11 = (s11 + (1 << 20)) >> 21;
|
||||
s12 += carry11;
|
||||
s11 -= carry11 * (1 << 21);
|
||||
carry13 = (s13 + (1 << 20)) >> 21;
|
||||
s14 += carry13;
|
||||
s13 -= carry13 * (1 << 21);
|
||||
carry15 = (s15 + (1 << 20)) >> 21;
|
||||
s16 += carry15;
|
||||
s15 -= carry15 * (1 << 21);
|
||||
carry17 = (s17 + (1 << 20)) >> 21;
|
||||
s18 += carry17;
|
||||
s17 -= carry17 * (1 << 21);
|
||||
carry19 = (s19 + (1 << 20)) >> 21;
|
||||
s20 += carry19;
|
||||
s19 -= carry19 * (1 << 21);
|
||||
carry21 = (s21 + (1 << 20)) >> 21;
|
||||
s22 += carry21;
|
||||
s21 -= carry21 * (1 << 21);
|
||||
|
||||
s11 += s23 * 666643;
|
||||
s12 += s23 * 470296;
|
||||
s13 += s23 * 654183;
|
||||
s14 -= s23 * 997805;
|
||||
s15 += s23 * 136657;
|
||||
s16 -= s23 * 683901;
|
||||
s23 = 0;
|
||||
|
||||
s10 += s22 * 666643;
|
||||
s11 += s22 * 470296;
|
||||
s12 += s22 * 654183;
|
||||
s13 -= s22 * 997805;
|
||||
s14 += s22 * 136657;
|
||||
s15 -= s22 * 683901;
|
||||
s22 = 0;
|
||||
|
||||
s9 += s21 * 666643;
|
||||
s10 += s21 * 470296;
|
||||
s11 += s21 * 654183;
|
||||
s12 -= s21 * 997805;
|
||||
s13 += s21 * 136657;
|
||||
s14 -= s21 * 683901;
|
||||
s21 = 0;
|
||||
|
||||
s8 += s20 * 666643;
|
||||
s9 += s20 * 470296;
|
||||
s10 += s20 * 654183;
|
||||
s11 -= s20 * 997805;
|
||||
s12 += s20 * 136657;
|
||||
s13 -= s20 * 683901;
|
||||
s20 = 0;
|
||||
|
||||
s7 += s19 * 666643;
|
||||
s8 += s19 * 470296;
|
||||
s9 += s19 * 654183;
|
||||
s10 -= s19 * 997805;
|
||||
s11 += s19 * 136657;
|
||||
s12 -= s19 * 683901;
|
||||
s19 = 0;
|
||||
|
||||
s6 += s18 * 666643;
|
||||
s7 += s18 * 470296;
|
||||
s8 += s18 * 654183;
|
||||
s9 -= s18 * 997805;
|
||||
s10 += s18 * 136657;
|
||||
s11 -= s18 * 683901;
|
||||
s18 = 0;
|
||||
|
||||
carry6 = (s6 + (1 << 20)) >> 21;
|
||||
s7 += carry6;
|
||||
s6 -= carry6 * (1 << 21);
|
||||
carry8 = (s8 + (1 << 20)) >> 21;
|
||||
s9 += carry8;
|
||||
s8 -= carry8 * (1 << 21);
|
||||
carry10 = (s10 + (1 << 20)) >> 21;
|
||||
s11 += carry10;
|
||||
s10 -= carry10 * (1 << 21);
|
||||
carry12 = (s12 + (1 << 20)) >> 21;
|
||||
s13 += carry12;
|
||||
s12 -= carry12 * (1 << 21);
|
||||
carry14 = (s14 + (1 << 20)) >> 21;
|
||||
s15 += carry14;
|
||||
s14 -= carry14 * (1 << 21);
|
||||
carry16 = (s16 + (1 << 20)) >> 21;
|
||||
s17 += carry16;
|
||||
s16 -= carry16 * (1 << 21);
|
||||
|
||||
carry7 = (s7 + (1 << 20)) >> 21;
|
||||
s8 += carry7;
|
||||
s7 -= carry7 * (1 << 21);
|
||||
carry9 = (s9 + (1 << 20)) >> 21;
|
||||
s10 += carry9;
|
||||
s9 -= carry9 * (1 << 21);
|
||||
carry11 = (s11 + (1 << 20)) >> 21;
|
||||
s12 += carry11;
|
||||
s11 -= carry11 * (1 << 21);
|
||||
carry13 = (s13 + (1 << 20)) >> 21;
|
||||
s14 += carry13;
|
||||
s13 -= carry13 * (1 << 21);
|
||||
carry15 = (s15 + (1 << 20)) >> 21;
|
||||
s16 += carry15;
|
||||
s15 -= carry15 * (1 << 21);
|
||||
|
||||
s5 += s17 * 666643;
|
||||
s6 += s17 * 470296;
|
||||
s7 += s17 * 654183;
|
||||
s8 -= s17 * 997805;
|
||||
s9 += s17 * 136657;
|
||||
s10 -= s17 * 683901;
|
||||
s17 = 0;
|
||||
|
||||
s4 += s16 * 666643;
|
||||
s5 += s16 * 470296;
|
||||
s6 += s16 * 654183;
|
||||
s7 -= s16 * 997805;
|
||||
s8 += s16 * 136657;
|
||||
s9 -= s16 * 683901;
|
||||
s16 = 0;
|
||||
|
||||
s3 += s15 * 666643;
|
||||
s4 += s15 * 470296;
|
||||
s5 += s15 * 654183;
|
||||
s6 -= s15 * 997805;
|
||||
s7 += s15 * 136657;
|
||||
s8 -= s15 * 683901;
|
||||
s15 = 0;
|
||||
|
||||
s2 += s14 * 666643;
|
||||
s3 += s14 * 470296;
|
||||
s4 += s14 * 654183;
|
||||
s5 -= s14 * 997805;
|
||||
s6 += s14 * 136657;
|
||||
s7 -= s14 * 683901;
|
||||
s14 = 0;
|
||||
|
||||
s1 += s13 * 666643;
|
||||
s2 += s13 * 470296;
|
||||
s3 += s13 * 654183;
|
||||
s4 -= s13 * 997805;
|
||||
s5 += s13 * 136657;
|
||||
s6 -= s13 * 683901;
|
||||
s13 = 0;
|
||||
|
||||
s0 += s12 * 666643;
|
||||
s1 += s12 * 470296;
|
||||
s2 += s12 * 654183;
|
||||
s3 -= s12 * 997805;
|
||||
s4 += s12 * 136657;
|
||||
s5 -= s12 * 683901;
|
||||
s12 = 0;
|
||||
|
||||
carry0 = (s0 + (1 << 20)) >> 21;
|
||||
s1 += carry0;
|
||||
s0 -= carry0 * (1 << 21);
|
||||
carry2 = (s2 + (1 << 20)) >> 21;
|
||||
s3 += carry2;
|
||||
s2 -= carry2 * (1 << 21);
|
||||
carry4 = (s4 + (1 << 20)) >> 21;
|
||||
s5 += carry4;
|
||||
s4 -= carry4 * (1 << 21);
|
||||
carry6 = (s6 + (1 << 20)) >> 21;
|
||||
s7 += carry6;
|
||||
s6 -= carry6 * (1 << 21);
|
||||
carry8 = (s8 + (1 << 20)) >> 21;
|
||||
s9 += carry8;
|
||||
s8 -= carry8 * (1 << 21);
|
||||
carry10 = (s10 + (1 << 20)) >> 21;
|
||||
s11 += carry10;
|
||||
s10 -= carry10 * (1 << 21);
|
||||
|
||||
carry1 = (s1 + (1 << 20)) >> 21;
|
||||
s2 += carry1;
|
||||
s1 -= carry1 * (1 << 21);
|
||||
carry3 = (s3 + (1 << 20)) >> 21;
|
||||
s4 += carry3;
|
||||
s3 -= carry3 * (1 << 21);
|
||||
carry5 = (s5 + (1 << 20)) >> 21;
|
||||
s6 += carry5;
|
||||
s5 -= carry5 * (1 << 21);
|
||||
carry7 = (s7 + (1 << 20)) >> 21;
|
||||
s8 += carry7;
|
||||
s7 -= carry7 * (1 << 21);
|
||||
carry9 = (s9 + (1 << 20)) >> 21;
|
||||
s10 += carry9;
|
||||
s9 -= carry9 * (1 << 21);
|
||||
carry11 = (s11 + (1 << 20)) >> 21;
|
||||
s12 += carry11;
|
||||
s11 -= carry11 * (1 << 21);
|
||||
|
||||
s0 += s12 * 666643;
|
||||
s1 += s12 * 470296;
|
||||
s2 += s12 * 654183;
|
||||
s3 -= s12 * 997805;
|
||||
s4 += s12 * 136657;
|
||||
s5 -= s12 * 683901;
|
||||
s12 = 0;
|
||||
|
||||
carry0 = s0 >> 21;
|
||||
s1 += carry0;
|
||||
s0 -= carry0 * (1 << 21);
|
||||
carry1 = s1 >> 21;
|
||||
s2 += carry1;
|
||||
s1 -= carry1 * (1 << 21);
|
||||
carry2 = s2 >> 21;
|
||||
s3 += carry2;
|
||||
s2 -= carry2 * (1 << 21);
|
||||
carry3 = s3 >> 21;
|
||||
s4 += carry3;
|
||||
s3 -= carry3 * (1 << 21);
|
||||
carry4 = s4 >> 21;
|
||||
s5 += carry4;
|
||||
s4 -= carry4 * (1 << 21);
|
||||
carry5 = s5 >> 21;
|
||||
s6 += carry5;
|
||||
s5 -= carry5 * (1 << 21);
|
||||
carry6 = s6 >> 21;
|
||||
s7 += carry6;
|
||||
s6 -= carry6 * (1 << 21);
|
||||
carry7 = s7 >> 21;
|
||||
s8 += carry7;
|
||||
s7 -= carry7 * (1 << 21);
|
||||
carry8 = s8 >> 21;
|
||||
s9 += carry8;
|
||||
s8 -= carry8 * (1 << 21);
|
||||
carry9 = s9 >> 21;
|
||||
s10 += carry9;
|
||||
s9 -= carry9 * (1 << 21);
|
||||
carry10 = s10 >> 21;
|
||||
s11 += carry10;
|
||||
s10 -= carry10 * (1 << 21);
|
||||
carry11 = s11 >> 21;
|
||||
s12 += carry11;
|
||||
s11 -= carry11 * (1 << 21);
|
||||
|
||||
s0 += s12 * 666643;
|
||||
s1 += s12 * 470296;
|
||||
s2 += s12 * 654183;
|
||||
s3 -= s12 * 997805;
|
||||
s4 += s12 * 136657;
|
||||
s5 -= s12 * 683901;
|
||||
s12 = 0;
|
||||
|
||||
carry0 = s0 >> 21;
|
||||
s1 += carry0;
|
||||
s0 -= carry0 * (1 << 21);
|
||||
carry1 = s1 >> 21;
|
||||
s2 += carry1;
|
||||
s1 -= carry1 * (1 << 21);
|
||||
carry2 = s2 >> 21;
|
||||
s3 += carry2;
|
||||
s2 -= carry2 * (1 << 21);
|
||||
carry3 = s3 >> 21;
|
||||
s4 += carry3;
|
||||
s3 -= carry3 * (1 << 21);
|
||||
carry4 = s4 >> 21;
|
||||
s5 += carry4;
|
||||
s4 -= carry4 * (1 << 21);
|
||||
carry5 = s5 >> 21;
|
||||
s6 += carry5;
|
||||
s5 -= carry5 * (1 << 21);
|
||||
carry6 = s6 >> 21;
|
||||
s7 += carry6;
|
||||
s6 -= carry6 * (1 << 21);
|
||||
carry7 = s7 >> 21;
|
||||
s8 += carry7;
|
||||
s7 -= carry7 * (1 << 21);
|
||||
carry8 = s8 >> 21;
|
||||
s9 += carry8;
|
||||
s8 -= carry8 * (1 << 21);
|
||||
carry9 = s9 >> 21;
|
||||
s10 += carry9;
|
||||
s9 -= carry9 * (1 << 21);
|
||||
carry10 = s10 >> 21;
|
||||
s11 += carry10;
|
||||
s10 -= carry10 * (1 << 21);
|
||||
|
||||
s[0] = (uint8_t)(s0 >> 0);
|
||||
s[1] = (uint8_t)(s0 >> 8);
|
||||
s[2] = (uint8_t)((s0 >> 16) | (s1 << 5));
|
||||
s[3] = (uint8_t)(s1 >> 3);
|
||||
s[4] = (uint8_t)(s1 >> 11);
|
||||
s[5] = (uint8_t)((s1 >> 19) | (s2 << 2));
|
||||
s[6] = (uint8_t)(s2 >> 6);
|
||||
s[7] = (uint8_t)((s2 >> 14) | (s3 << 7));
|
||||
s[8] = (uint8_t)(s3 >> 1);
|
||||
s[9] = (uint8_t)(s3 >> 9);
|
||||
s[10] = (uint8_t)((s3 >> 17) | (s4 << 4));
|
||||
s[11] = (uint8_t)(s4 >> 4);
|
||||
s[12] = (uint8_t)(s4 >> 12);
|
||||
s[13] = (uint8_t)((s4 >> 20) | (s5 << 1));
|
||||
s[14] = (uint8_t)(s5 >> 7);
|
||||
s[15] = (uint8_t)((s5 >> 15) | (s6 << 6));
|
||||
s[16] = (uint8_t)(s6 >> 2);
|
||||
s[17] = (uint8_t)(s6 >> 10);
|
||||
s[18] = (uint8_t)((s6 >> 18) | (s7 << 3));
|
||||
s[19] = (uint8_t)(s7 >> 5);
|
||||
s[20] = (uint8_t)(s7 >> 13);
|
||||
s[21] = (uint8_t)(s8 >> 0);
|
||||
s[22] = (uint8_t)(s8 >> 8);
|
||||
s[23] = (uint8_t)((s8 >> 16) | (s9 << 5));
|
||||
s[24] = (uint8_t)(s9 >> 3);
|
||||
s[25] = (uint8_t)(s9 >> 11);
|
||||
s[26] = (uint8_t)((s9 >> 19) | (s10 << 2));
|
||||
s[27] = (uint8_t)(s10 >> 6);
|
||||
s[28] = (uint8_t)((s10 >> 14) | (s11 << 7));
|
||||
s[29] = (uint8_t)(s11 >> 1);
|
||||
s[30] = (uint8_t)(s11 >> 9);
|
||||
s[31] = (uint8_t)(s11 >> 17);
|
||||
}
|
||||
|
||||
int ED25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len,
|
||||
const uint8_t public_key[32], const uint8_t private_key[32]) {
|
||||
uint8_t az[SHA512_DIGEST_LENGTH];
|
||||
uint8_t nonce[SHA512_DIGEST_LENGTH];
|
||||
ge_p3 R;
|
||||
uint8_t hram[SHA512_DIGEST_LENGTH];
|
||||
SHA512_CTX hash_ctx;
|
||||
|
||||
SHA512_Init(&hash_ctx);
|
||||
SHA512_Update(&hash_ctx, private_key, 32);
|
||||
SHA512_Final(az, &hash_ctx);
|
||||
|
||||
az[0] &= 248;
|
||||
az[31] &= 63;
|
||||
az[31] |= 64;
|
||||
|
||||
SHA512_Init(&hash_ctx);
|
||||
SHA512_Update(&hash_ctx, az + 32, 32);
|
||||
SHA512_Update(&hash_ctx, message, message_len);
|
||||
SHA512_Final(nonce, &hash_ctx);
|
||||
|
||||
x25519_sc_reduce(nonce);
|
||||
ge_scalarmult_base(&R, nonce);
|
||||
ge_p3_tobytes(out_sig, &R);
|
||||
|
||||
SHA512_Init(&hash_ctx);
|
||||
SHA512_Update(&hash_ctx, out_sig, 32);
|
||||
SHA512_Update(&hash_ctx, public_key, 32);
|
||||
SHA512_Update(&hash_ctx, message, message_len);
|
||||
SHA512_Final(hram, &hash_ctx);
|
||||
|
||||
x25519_sc_reduce(hram);
|
||||
sc_muladd(out_sig + 32, hram, az, nonce);
|
||||
|
||||
OPENSSL_cleanse(&hash_ctx, sizeof(hash_ctx));
|
||||
OPENSSL_cleanse(nonce, sizeof(nonce));
|
||||
OPENSSL_cleanse(az, sizeof(az));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ED25519_verify(const uint8_t *message, size_t message_len,
|
||||
const uint8_t signature[64], const uint8_t public_key[32]) {
|
||||
ge_p3 A;
|
||||
uint8_t rcopy[32];
|
||||
uint8_t scopy[32];
|
||||
SHA512_CTX hash_ctx;
|
||||
ge_p2 R;
|
||||
uint8_t rcheck[32];
|
||||
uint8_t h[SHA512_DIGEST_LENGTH];
|
||||
|
||||
if ((signature[63] & 224) != 0 ||
|
||||
ge_frombytes_vartime(&A, public_key) != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
fe_neg(A.X, A.X);
|
||||
fe_neg(A.T, A.T);
|
||||
|
||||
memcpy(rcopy, signature, 32);
|
||||
memcpy(scopy, signature + 32, 32);
|
||||
|
||||
SHA512_Init(&hash_ctx);
|
||||
SHA512_Update(&hash_ctx, signature, 32);
|
||||
SHA512_Update(&hash_ctx, public_key, 32);
|
||||
SHA512_Update(&hash_ctx, message, message_len);
|
||||
SHA512_Final(h, &hash_ctx);
|
||||
|
||||
x25519_sc_reduce(h);
|
||||
|
||||
ge_double_scalarmult_vartime(&R, h, &A, scopy);
|
||||
|
||||
ge_tobytes(rcheck, &R);
|
||||
|
||||
return CRYPTO_memcmp(rcheck, rcopy, sizeof(rcheck)) == 0;
|
||||
}
|
||||
|
||||
void ED25519_public_from_private(uint8_t out_public_key[32],
|
||||
const uint8_t private_key[32]) {
|
||||
uint8_t az[SHA512_DIGEST_LENGTH];
|
||||
ge_p3 A;
|
||||
|
||||
SHA512(private_key, 32, az);
|
||||
|
||||
az[0] &= 248;
|
||||
az[31] &= 63;
|
||||
az[31] |= 64;
|
||||
|
||||
ge_scalarmult_base(&A, az);
|
||||
ge_p3_tobytes(out_public_key, &A);
|
||||
|
||||
OPENSSL_cleanse(az, sizeof(az));
|
||||
}
|
||||
|
||||
int X25519(uint8_t out_shared_key[32], const uint8_t private_key[32],
|
||||
const uint8_t peer_public_value[32]) {
|
||||
static const uint8_t kZeros[32] = {0};
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2016 Cryptography Research, 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 Mike Hamburg
|
||||
*/
|
||||
|
||||
#ifndef HEADER_ARCH_32_ARCH_INTRINSICS_H
|
||||
# define HEADER_ARCH_32_ARCH_INTRINSICS_H
|
||||
|
||||
#include "internal/constant_time_locl.h"
|
||||
|
||||
# define ARCH_WORD_BITS 32
|
||||
|
||||
#define word_is_zero(a) constant_time_is_zero_32(a)
|
||||
|
||||
static ossl_inline uint64_t widemul(uint32_t a, uint32_t b)
|
||||
{
|
||||
return ((uint64_t)a) * b;
|
||||
}
|
||||
|
||||
#endif /* HEADER_ARCH_32_ARCH_INTRINSICS_H */
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2014 Cryptography Research, 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 Mike Hamburg
|
||||
*/
|
||||
|
||||
#include "field.h"
|
||||
|
||||
void gf_mul(gf_s * RESTRICT cs, const gf as, const gf bs)
|
||||
{
|
||||
const uint32_t *a = as->limb, *b = bs->limb;
|
||||
uint32_t *c = cs->limb;
|
||||
uint64_t accum0 = 0, accum1 = 0, accum2 = 0;
|
||||
uint32_t mask = (1 << 28) - 1;
|
||||
uint32_t aa[8], bb[8];
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
aa[i] = a[i] + a[i + 8];
|
||||
bb[i] = b[i] + b[i + 8];
|
||||
}
|
||||
|
||||
for (j = 0; j < 8; j++) {
|
||||
accum2 = 0;
|
||||
for (i = 0; i < j + 1; i++) {
|
||||
accum2 += widemul(a[j - i], b[i]);
|
||||
accum1 += widemul(aa[j - i], bb[i]);
|
||||
accum0 += widemul(a[8 + j - i], b[8 + i]);
|
||||
}
|
||||
accum1 -= accum2;
|
||||
accum0 += accum2;
|
||||
accum2 = 0;
|
||||
for (i = j + 1; i < 8; i++) {
|
||||
accum0 -= widemul(a[8 + j - i], b[i]);
|
||||
accum2 += widemul(aa[8 + j - i], bb[i]);
|
||||
accum1 += widemul(a[16 + j - i], b[8 + i]);
|
||||
}
|
||||
accum1 += accum2;
|
||||
accum0 += accum2;
|
||||
c[j] = ((uint32_t)(accum0)) & mask;
|
||||
c[j + 8] = ((uint32_t)(accum1)) & mask;
|
||||
accum0 >>= 28;
|
||||
accum1 >>= 28;
|
||||
}
|
||||
|
||||
accum0 += accum1;
|
||||
accum0 += c[8];
|
||||
accum1 += c[0];
|
||||
c[8] = ((uint32_t)(accum0)) & mask;
|
||||
c[0] = ((uint32_t)(accum1)) & mask;
|
||||
|
||||
accum0 >>= 28;
|
||||
accum1 >>= 28;
|
||||
c[9] += ((uint32_t)(accum0));
|
||||
c[1] += ((uint32_t)(accum1));
|
||||
}
|
||||
|
||||
void gf_mulw_unsigned(gf_s * RESTRICT cs, const gf as, uint32_t b)
|
||||
{
|
||||
const uint32_t *a = as->limb;
|
||||
uint32_t *c = cs->limb;
|
||||
uint64_t accum0 = 0, accum8 = 0;
|
||||
uint32_t mask = (1 << 28) - 1;
|
||||
int i;
|
||||
|
||||
assert(b <= mask);
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
accum0 += widemul(b, a[i]);
|
||||
accum8 += widemul(b, a[i + 8]);
|
||||
c[i] = accum0 & mask;
|
||||
accum0 >>= 28;
|
||||
c[i + 8] = accum8 & mask;
|
||||
accum8 >>= 28;
|
||||
}
|
||||
|
||||
accum0 += accum8 + c[8];
|
||||
c[8] = ((uint32_t)accum0) & mask;
|
||||
c[9] += (uint32_t)(accum0 >> 28);
|
||||
|
||||
accum8 += c[0];
|
||||
c[0] = ((uint32_t)accum8) & mask;
|
||||
c[1] += (uint32_t)(accum8 >> 28);
|
||||
}
|
||||
|
||||
void gf_sqr(gf_s * RESTRICT cs, const gf as)
|
||||
{
|
||||
gf_mul(cs, as, as); /* Performs better with a dedicated square */
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2014-2016 Cryptography Research, 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 Mike Hamburg
|
||||
*/
|
||||
|
||||
#ifndef HEADER_ARCH_32_F_IMPL_H
|
||||
# define HEADER_ARCH_32_F_IMPL_H
|
||||
|
||||
# define GF_HEADROOM 2
|
||||
# define LIMB(x) ((x) & ((1 << 28) - 1)), ((x) >> 28)
|
||||
# define FIELD_LITERAL(a, b, c, d, e, f, g, h) \
|
||||
{{LIMB(a), LIMB(b), LIMB(c), LIMB(d), LIMB(e), LIMB(f), LIMB(g), LIMB(h)}}
|
||||
|
||||
# define LIMB_PLACE_VALUE(i) 28
|
||||
|
||||
void gf_add_RAW(gf out, const gf a, const gf b)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < NLIMBS; i++)
|
||||
out->limb[i] = a->limb[i] + b->limb[i];
|
||||
}
|
||||
|
||||
void gf_sub_RAW(gf out, const gf a, const gf b)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < NLIMBS; i++)
|
||||
out->limb[i] = a->limb[i] - b->limb[i];
|
||||
}
|
||||
|
||||
void gf_bias(gf a, int amt)
|
||||
{
|
||||
unsigned int i;
|
||||
uint32_t co1 = ((1 << 28) - 1) * amt, co2 = co1 - amt;
|
||||
|
||||
for (i = 0; i < NLIMBS; i++)
|
||||
a->limb[i] += (i == NLIMBS / 2) ? co2 : co1;
|
||||
}
|
||||
|
||||
void gf_weak_reduce(gf a)
|
||||
{
|
||||
uint32_t mask = (1 << 28) - 1;
|
||||
uint32_t tmp = a->limb[NLIMBS - 1] >> 28;
|
||||
unsigned int i;
|
||||
|
||||
a->limb[NLIMBS / 2] += tmp;
|
||||
for (i = NLIMBS - 1; i > 0; i--)
|
||||
a->limb[i] = (a->limb[i] & mask) + (a->limb[i - 1] >> 28);
|
||||
a->limb[0] = (a->limb[0] & mask) + tmp;
|
||||
}
|
||||
|
||||
#endif /* HEADER_ARCH_32_F_IMPL_H */
|
||||
@@ -0,0 +1,727 @@
|
||||
/*
|
||||
* Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2015-2016 Cryptography Research, 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 Mike Hamburg
|
||||
*/
|
||||
#include <openssl/crypto.h>
|
||||
#include "word.h"
|
||||
#include "field.h"
|
||||
|
||||
#include "point_448.h"
|
||||
#include "ed448.h"
|
||||
#include "curve448_lcl.h"
|
||||
|
||||
#define COFACTOR 4
|
||||
|
||||
#define C448_WNAF_FIXED_TABLE_BITS 5
|
||||
#define C448_WNAF_VAR_TABLE_BITS 3
|
||||
|
||||
#define EDWARDS_D (-39081)
|
||||
|
||||
static const curve448_scalar_t precomputed_scalarmul_adjustment = {
|
||||
{
|
||||
{
|
||||
SC_LIMB(0xc873d6d54a7bb0cf), SC_LIMB(0xe933d8d723a70aad),
|
||||
SC_LIMB(0xbb124b65129c96fd), SC_LIMB(0x00000008335dc163)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#define TWISTED_D (EDWARDS_D - 1)
|
||||
|
||||
#define WBITS C448_WORD_BITS /* NB this may be different from ARCH_WORD_BITS */
|
||||
|
||||
/* Inverse. */
|
||||
static void gf_invert(gf y, const gf x, int assert_nonzero)
|
||||
{
|
||||
mask_t ret;
|
||||
gf t1, t2;
|
||||
|
||||
gf_sqr(t1, x); /* o^2 */
|
||||
ret = gf_isr(t2, t1); /* +-1/sqrt(o^2) = +-1/o */
|
||||
(void)ret;
|
||||
if (assert_nonzero)
|
||||
assert(ret);
|
||||
gf_sqr(t1, t2);
|
||||
gf_mul(t2, t1, x); /* not direct to y in case of alias. */
|
||||
gf_copy(y, t2);
|
||||
}
|
||||
|
||||
/** identity = (0,1) */
|
||||
const curve448_point_t curve448_point_identity =
|
||||
{ {{{{0}}}, {{{1}}}, {{{1}}}, {{{0}}}} };
|
||||
|
||||
static void point_double_internal(curve448_point_t p, const curve448_point_t q,
|
||||
int before_double)
|
||||
{
|
||||
gf a, b, c, d;
|
||||
|
||||
gf_sqr(c, q->x);
|
||||
gf_sqr(a, q->y);
|
||||
gf_add_nr(d, c, a); /* 2+e */
|
||||
gf_add_nr(p->t, q->y, q->x); /* 2+e */
|
||||
gf_sqr(b, p->t);
|
||||
gf_subx_nr(b, b, d, 3); /* 4+e */
|
||||
gf_sub_nr(p->t, a, c); /* 3+e */
|
||||
gf_sqr(p->x, q->z);
|
||||
gf_add_nr(p->z, p->x, p->x); /* 2+e */
|
||||
gf_subx_nr(a, p->z, p->t, 4); /* 6+e */
|
||||
if (GF_HEADROOM == 5)
|
||||
gf_weak_reduce(a); /* or 1+e */
|
||||
gf_mul(p->x, a, b);
|
||||
gf_mul(p->z, p->t, a);
|
||||
gf_mul(p->y, p->t, d);
|
||||
if (!before_double)
|
||||
gf_mul(p->t, b, d);
|
||||
}
|
||||
|
||||
void curve448_point_double(curve448_point_t p, const curve448_point_t q)
|
||||
{
|
||||
point_double_internal(p, q, 0);
|
||||
}
|
||||
|
||||
/* Operations on [p]niels */
|
||||
static ossl_inline void cond_neg_niels(niels_t n, mask_t neg)
|
||||
{
|
||||
gf_cond_swap(n->a, n->b, neg);
|
||||
gf_cond_neg(n->c, neg);
|
||||
}
|
||||
|
||||
static void pt_to_pniels(pniels_t b, const curve448_point_t a)
|
||||
{
|
||||
gf_sub(b->n->a, a->y, a->x);
|
||||
gf_add(b->n->b, a->x, a->y);
|
||||
gf_mulw(b->n->c, a->t, 2 * TWISTED_D);
|
||||
gf_add(b->z, a->z, a->z);
|
||||
}
|
||||
|
||||
static void pniels_to_pt(curve448_point_t e, const pniels_t d)
|
||||
{
|
||||
gf eu;
|
||||
|
||||
gf_add(eu, d->n->b, d->n->a);
|
||||
gf_sub(e->y, d->n->b, d->n->a);
|
||||
gf_mul(e->t, e->y, eu);
|
||||
gf_mul(e->x, d->z, e->y);
|
||||
gf_mul(e->y, d->z, eu);
|
||||
gf_sqr(e->z, d->z);
|
||||
}
|
||||
|
||||
static void niels_to_pt(curve448_point_t e, const niels_t n)
|
||||
{
|
||||
gf_add(e->y, n->b, n->a);
|
||||
gf_sub(e->x, n->b, n->a);
|
||||
gf_mul(e->t, e->y, e->x);
|
||||
gf_copy(e->z, ONE);
|
||||
}
|
||||
|
||||
static void add_niels_to_pt(curve448_point_t d, const niels_t e,
|
||||
int before_double)
|
||||
{
|
||||
gf a, b, c;
|
||||
|
||||
gf_sub_nr(b, d->y, d->x); /* 3+e */
|
||||
gf_mul(a, e->a, b);
|
||||
gf_add_nr(b, d->x, d->y); /* 2+e */
|
||||
gf_mul(d->y, e->b, b);
|
||||
gf_mul(d->x, e->c, d->t);
|
||||
gf_add_nr(c, a, d->y); /* 2+e */
|
||||
gf_sub_nr(b, d->y, a); /* 3+e */
|
||||
gf_sub_nr(d->y, d->z, d->x); /* 3+e */
|
||||
gf_add_nr(a, d->x, d->z); /* 2+e */
|
||||
gf_mul(d->z, a, d->y);
|
||||
gf_mul(d->x, d->y, b);
|
||||
gf_mul(d->y, a, c);
|
||||
if (!before_double)
|
||||
gf_mul(d->t, b, c);
|
||||
}
|
||||
|
||||
static void sub_niels_from_pt(curve448_point_t d, const niels_t e,
|
||||
int before_double)
|
||||
{
|
||||
gf a, b, c;
|
||||
|
||||
gf_sub_nr(b, d->y, d->x); /* 3+e */
|
||||
gf_mul(a, e->b, b);
|
||||
gf_add_nr(b, d->x, d->y); /* 2+e */
|
||||
gf_mul(d->y, e->a, b);
|
||||
gf_mul(d->x, e->c, d->t);
|
||||
gf_add_nr(c, a, d->y); /* 2+e */
|
||||
gf_sub_nr(b, d->y, a); /* 3+e */
|
||||
gf_add_nr(d->y, d->z, d->x); /* 2+e */
|
||||
gf_sub_nr(a, d->z, d->x); /* 3+e */
|
||||
gf_mul(d->z, a, d->y);
|
||||
gf_mul(d->x, d->y, b);
|
||||
gf_mul(d->y, a, c);
|
||||
if (!before_double)
|
||||
gf_mul(d->t, b, c);
|
||||
}
|
||||
|
||||
static void add_pniels_to_pt(curve448_point_t p, const pniels_t pn,
|
||||
int before_double)
|
||||
{
|
||||
gf L0;
|
||||
|
||||
gf_mul(L0, p->z, pn->z);
|
||||
gf_copy(p->z, L0);
|
||||
add_niels_to_pt(p, pn->n, before_double);
|
||||
}
|
||||
|
||||
static void sub_pniels_from_pt(curve448_point_t p, const pniels_t pn,
|
||||
int before_double)
|
||||
{
|
||||
gf L0;
|
||||
|
||||
gf_mul(L0, p->z, pn->z);
|
||||
gf_copy(p->z, L0);
|
||||
sub_niels_from_pt(p, pn->n, before_double);
|
||||
}
|
||||
|
||||
c448_bool_t curve448_point_eq(const curve448_point_t p,
|
||||
const curve448_point_t q)
|
||||
{
|
||||
mask_t succ;
|
||||
gf a, b;
|
||||
|
||||
/* equality mod 2-torsion compares x/y */
|
||||
gf_mul(a, p->y, q->x);
|
||||
gf_mul(b, q->y, p->x);
|
||||
succ = gf_eq(a, b);
|
||||
|
||||
return mask_to_bool(succ);
|
||||
}
|
||||
|
||||
c448_bool_t curve448_point_valid(const curve448_point_t p)
|
||||
{
|
||||
mask_t out;
|
||||
gf a, b, c;
|
||||
|
||||
gf_mul(a, p->x, p->y);
|
||||
gf_mul(b, p->z, p->t);
|
||||
out = gf_eq(a, b);
|
||||
gf_sqr(a, p->x);
|
||||
gf_sqr(b, p->y);
|
||||
gf_sub(a, b, a);
|
||||
gf_sqr(b, p->t);
|
||||
gf_mulw(c, b, TWISTED_D);
|
||||
gf_sqr(b, p->z);
|
||||
gf_add(b, b, c);
|
||||
out &= gf_eq(a, b);
|
||||
out &= ~gf_eq(p->z, ZERO);
|
||||
return mask_to_bool(out);
|
||||
}
|
||||
|
||||
static ossl_inline void constant_time_lookup_niels(niels_s * RESTRICT ni,
|
||||
const niels_t * table,
|
||||
int nelts, int idx)
|
||||
{
|
||||
constant_time_lookup(ni, table, sizeof(niels_s), nelts, idx);
|
||||
}
|
||||
|
||||
void curve448_precomputed_scalarmul(curve448_point_t out,
|
||||
const curve448_precomputed_s * table,
|
||||
const curve448_scalar_t scalar)
|
||||
{
|
||||
unsigned int i, j, k;
|
||||
const unsigned int n = COMBS_N, t = COMBS_T, s = COMBS_S;
|
||||
niels_t ni;
|
||||
curve448_scalar_t scalar1x;
|
||||
|
||||
curve448_scalar_add(scalar1x, scalar, precomputed_scalarmul_adjustment);
|
||||
curve448_scalar_halve(scalar1x, scalar1x);
|
||||
|
||||
for (i = s; i > 0; i--) {
|
||||
if (i != s)
|
||||
point_double_internal(out, out, 0);
|
||||
|
||||
for (j = 0; j < n; j++) {
|
||||
int tab = 0;
|
||||
mask_t invert;
|
||||
|
||||
for (k = 0; k < t; k++) {
|
||||
unsigned int bit = (i - 1) + s * (k + j * t);
|
||||
|
||||
if (bit < C448_SCALAR_BITS)
|
||||
tab |=
|
||||
(scalar1x->limb[bit / WBITS] >> (bit % WBITS) & 1) << k;
|
||||
}
|
||||
|
||||
invert = (tab >> (t - 1)) - 1;
|
||||
tab ^= invert;
|
||||
tab &= (1 << (t - 1)) - 1;
|
||||
|
||||
constant_time_lookup_niels(ni, &table->table[j << (t - 1)],
|
||||
1 << (t - 1), tab);
|
||||
|
||||
cond_neg_niels(ni, invert);
|
||||
if ((i != s) || j != 0)
|
||||
add_niels_to_pt(out, ni, j == n - 1 && i != 1);
|
||||
else
|
||||
niels_to_pt(out, ni);
|
||||
}
|
||||
}
|
||||
|
||||
OPENSSL_cleanse(ni, sizeof(ni));
|
||||
OPENSSL_cleanse(scalar1x, sizeof(scalar1x));
|
||||
}
|
||||
|
||||
void curve448_point_mul_by_ratio_and_encode_like_eddsa(
|
||||
uint8_t enc[EDDSA_448_PUBLIC_BYTES],
|
||||
const curve448_point_t p)
|
||||
{
|
||||
gf x, y, z, t;
|
||||
curve448_point_t q;
|
||||
|
||||
/* The point is now on the twisted curve. Move it to untwisted. */
|
||||
curve448_point_copy(q, p);
|
||||
|
||||
{
|
||||
/* 4-isogeny: 2xy/(y^+x^2), (y^2-x^2)/(2z^2-y^2+x^2) */
|
||||
gf u;
|
||||
|
||||
gf_sqr(x, q->x);
|
||||
gf_sqr(t, q->y);
|
||||
gf_add(u, x, t);
|
||||
gf_add(z, q->y, q->x);
|
||||
gf_sqr(y, z);
|
||||
gf_sub(y, y, u);
|
||||
gf_sub(z, t, x);
|
||||
gf_sqr(x, q->z);
|
||||
gf_add(t, x, x);
|
||||
gf_sub(t, t, z);
|
||||
gf_mul(x, t, y);
|
||||
gf_mul(y, z, u);
|
||||
gf_mul(z, u, t);
|
||||
OPENSSL_cleanse(u, sizeof(u));
|
||||
}
|
||||
|
||||
/* Affinize */
|
||||
gf_invert(z, z, 1);
|
||||
gf_mul(t, x, z);
|
||||
gf_mul(x, y, z);
|
||||
|
||||
/* Encode */
|
||||
enc[EDDSA_448_PRIVATE_BYTES - 1] = 0;
|
||||
gf_serialize(enc, x, 1);
|
||||
enc[EDDSA_448_PRIVATE_BYTES - 1] |= 0x80 & gf_lobit(t);
|
||||
|
||||
OPENSSL_cleanse(x, sizeof(x));
|
||||
OPENSSL_cleanse(y, sizeof(y));
|
||||
OPENSSL_cleanse(z, sizeof(z));
|
||||
OPENSSL_cleanse(t, sizeof(t));
|
||||
curve448_point_destroy(q);
|
||||
}
|
||||
|
||||
c448_error_t curve448_point_decode_like_eddsa_and_mul_by_ratio(
|
||||
curve448_point_t p,
|
||||
const uint8_t enc[EDDSA_448_PUBLIC_BYTES])
|
||||
{
|
||||
uint8_t enc2[EDDSA_448_PUBLIC_BYTES];
|
||||
mask_t low;
|
||||
mask_t succ;
|
||||
|
||||
memcpy(enc2, enc, sizeof(enc2));
|
||||
|
||||
low = ~word_is_zero(enc2[EDDSA_448_PRIVATE_BYTES - 1] & 0x80);
|
||||
enc2[EDDSA_448_PRIVATE_BYTES - 1] &= ~0x80;
|
||||
|
||||
succ = gf_deserialize(p->y, enc2, 1, 0);
|
||||
succ &= word_is_zero(enc2[EDDSA_448_PRIVATE_BYTES - 1]);
|
||||
|
||||
gf_sqr(p->x, p->y);
|
||||
gf_sub(p->z, ONE, p->x); /* num = 1-y^2 */
|
||||
gf_mulw(p->t, p->x, EDWARDS_D); /* dy^2 */
|
||||
gf_sub(p->t, ONE, p->t); /* denom = 1-dy^2 or 1-d + dy^2 */
|
||||
|
||||
gf_mul(p->x, p->z, p->t);
|
||||
succ &= gf_isr(p->t, p->x); /* 1/sqrt(num * denom) */
|
||||
|
||||
gf_mul(p->x, p->t, p->z); /* sqrt(num / denom) */
|
||||
gf_cond_neg(p->x, gf_lobit(p->x) ^ low);
|
||||
gf_copy(p->z, ONE);
|
||||
|
||||
{
|
||||
gf a, b, c, d;
|
||||
|
||||
/* 4-isogeny 2xy/(y^2-ax^2), (y^2+ax^2)/(2-y^2-ax^2) */
|
||||
gf_sqr(c, p->x);
|
||||
gf_sqr(a, p->y);
|
||||
gf_add(d, c, a);
|
||||
gf_add(p->t, p->y, p->x);
|
||||
gf_sqr(b, p->t);
|
||||
gf_sub(b, b, d);
|
||||
gf_sub(p->t, a, c);
|
||||
gf_sqr(p->x, p->z);
|
||||
gf_add(p->z, p->x, p->x);
|
||||
gf_sub(a, p->z, d);
|
||||
gf_mul(p->x, a, b);
|
||||
gf_mul(p->z, p->t, a);
|
||||
gf_mul(p->y, p->t, d);
|
||||
gf_mul(p->t, b, d);
|
||||
OPENSSL_cleanse(a, sizeof(a));
|
||||
OPENSSL_cleanse(b, sizeof(b));
|
||||
OPENSSL_cleanse(c, sizeof(c));
|
||||
OPENSSL_cleanse(d, sizeof(d));
|
||||
}
|
||||
|
||||
OPENSSL_cleanse(enc2, sizeof(enc2));
|
||||
assert(curve448_point_valid(p) || ~succ);
|
||||
|
||||
return c448_succeed_if(mask_to_bool(succ));
|
||||
}
|
||||
|
||||
c448_error_t x448_int(uint8_t out[X_PUBLIC_BYTES],
|
||||
const uint8_t base[X_PUBLIC_BYTES],
|
||||
const uint8_t scalar[X_PRIVATE_BYTES])
|
||||
{
|
||||
gf x1, x2, z2, x3, z3, t1, t2;
|
||||
int t;
|
||||
mask_t swap = 0;
|
||||
mask_t nz;
|
||||
|
||||
(void)gf_deserialize(x1, base, 1, 0);
|
||||
gf_copy(x2, ONE);
|
||||
gf_copy(z2, ZERO);
|
||||
gf_copy(x3, x1);
|
||||
gf_copy(z3, ONE);
|
||||
|
||||
for (t = X_PRIVATE_BITS - 1; t >= 0; t--) {
|
||||
uint8_t sb = scalar[t / 8];
|
||||
mask_t k_t;
|
||||
|
||||
/* Scalar conditioning */
|
||||
if (t / 8 == 0)
|
||||
sb &= -(uint8_t)COFACTOR;
|
||||
else if (t == X_PRIVATE_BITS - 1)
|
||||
sb = -1;
|
||||
|
||||
k_t = (sb >> (t % 8)) & 1;
|
||||
k_t = 0 - k_t; /* set to all 0s or all 1s */
|
||||
|
||||
swap ^= k_t;
|
||||
gf_cond_swap(x2, x3, swap);
|
||||
gf_cond_swap(z2, z3, swap);
|
||||
swap = k_t;
|
||||
|
||||
/*
|
||||
* The "_nr" below skips coefficient reduction. In the following
|
||||
* comments, "2+e" is saying that the coefficients are at most 2+epsilon
|
||||
* times the reduction limit.
|
||||
*/
|
||||
gf_add_nr(t1, x2, z2); /* A = x2 + z2 */ /* 2+e */
|
||||
gf_sub_nr(t2, x2, z2); /* B = x2 - z2 */ /* 3+e */
|
||||
gf_sub_nr(z2, x3, z3); /* D = x3 - z3 */ /* 3+e */
|
||||
gf_mul(x2, t1, z2); /* DA */
|
||||
gf_add_nr(z2, z3, x3); /* C = x3 + z3 */ /* 2+e */
|
||||
gf_mul(x3, t2, z2); /* CB */
|
||||
gf_sub_nr(z3, x2, x3); /* DA-CB */ /* 3+e */
|
||||
gf_sqr(z2, z3); /* (DA-CB)^2 */
|
||||
gf_mul(z3, x1, z2); /* z3 = x1(DA-CB)^2 */
|
||||
gf_add_nr(z2, x2, x3); /* (DA+CB) */ /* 2+e */
|
||||
gf_sqr(x3, z2); /* x3 = (DA+CB)^2 */
|
||||
|
||||
gf_sqr(z2, t1); /* AA = A^2 */
|
||||
gf_sqr(t1, t2); /* BB = B^2 */
|
||||
gf_mul(x2, z2, t1); /* x2 = AA*BB */
|
||||
gf_sub_nr(t2, z2, t1); /* E = AA-BB */ /* 3+e */
|
||||
|
||||
gf_mulw(t1, t2, -EDWARDS_D); /* E*-d = a24*E */
|
||||
gf_add_nr(t1, t1, z2); /* AA + a24*E */ /* 2+e */
|
||||
gf_mul(z2, t2, t1); /* z2 = E(AA+a24*E) */
|
||||
}
|
||||
|
||||
/* Finish */
|
||||
gf_cond_swap(x2, x3, swap);
|
||||
gf_cond_swap(z2, z3, swap);
|
||||
gf_invert(z2, z2, 0);
|
||||
gf_mul(x1, x2, z2);
|
||||
gf_serialize(out, x1, 1);
|
||||
nz = ~gf_eq(x1, ZERO);
|
||||
|
||||
OPENSSL_cleanse(x1, sizeof(x1));
|
||||
OPENSSL_cleanse(x2, sizeof(x2));
|
||||
OPENSSL_cleanse(z2, sizeof(z2));
|
||||
OPENSSL_cleanse(x3, sizeof(x3));
|
||||
OPENSSL_cleanse(z3, sizeof(z3));
|
||||
OPENSSL_cleanse(t1, sizeof(t1));
|
||||
OPENSSL_cleanse(t2, sizeof(t2));
|
||||
|
||||
return c448_succeed_if(mask_to_bool(nz));
|
||||
}
|
||||
|
||||
void curve448_point_mul_by_ratio_and_encode_like_x448(uint8_t
|
||||
out[X_PUBLIC_BYTES],
|
||||
const curve448_point_t p)
|
||||
{
|
||||
curve448_point_t q;
|
||||
|
||||
curve448_point_copy(q, p);
|
||||
gf_invert(q->t, q->x, 0); /* 1/x */
|
||||
gf_mul(q->z, q->t, q->y); /* y/x */
|
||||
gf_sqr(q->y, q->z); /* (y/x)^2 */
|
||||
gf_serialize(out, q->y, 1);
|
||||
curve448_point_destroy(q);
|
||||
}
|
||||
|
||||
void x448_derive_public_key(uint8_t out[X_PUBLIC_BYTES],
|
||||
const uint8_t scalar[X_PRIVATE_BYTES])
|
||||
{
|
||||
/* Scalar conditioning */
|
||||
uint8_t scalar2[X_PRIVATE_BYTES];
|
||||
curve448_scalar_t the_scalar;
|
||||
curve448_point_t p;
|
||||
unsigned int i;
|
||||
|
||||
memcpy(scalar2, scalar, sizeof(scalar2));
|
||||
scalar2[0] &= -(uint8_t)COFACTOR;
|
||||
|
||||
scalar2[X_PRIVATE_BYTES - 1] &= ~((0u - 1u) << ((X_PRIVATE_BITS + 7) % 8));
|
||||
scalar2[X_PRIVATE_BYTES - 1] |= 1 << ((X_PRIVATE_BITS + 7) % 8);
|
||||
|
||||
curve448_scalar_decode_long(the_scalar, scalar2, sizeof(scalar2));
|
||||
|
||||
/* Compensate for the encoding ratio */
|
||||
for (i = 1; i < X448_ENCODE_RATIO; i <<= 1)
|
||||
curve448_scalar_halve(the_scalar, the_scalar);
|
||||
|
||||
curve448_precomputed_scalarmul(p, curve448_precomputed_base, the_scalar);
|
||||
curve448_point_mul_by_ratio_and_encode_like_x448(out, p);
|
||||
curve448_point_destroy(p);
|
||||
}
|
||||
|
||||
/* Control for variable-time scalar multiply algorithms. */
|
||||
struct smvt_control {
|
||||
int power, addend;
|
||||
};
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3))
|
||||
# define NUMTRAILINGZEROS __builtin_ctz
|
||||
#else
|
||||
# define NUMTRAILINGZEROS numtrailingzeros
|
||||
static uint32_t numtrailingzeros(uint32_t i)
|
||||
{
|
||||
uint32_t tmp;
|
||||
uint32_t num = 31;
|
||||
|
||||
if (i == 0)
|
||||
return 32;
|
||||
|
||||
tmp = i << 16;
|
||||
if (tmp != 0) {
|
||||
i = tmp;
|
||||
num -= 16;
|
||||
}
|
||||
tmp = i << 8;
|
||||
if (tmp != 0) {
|
||||
i = tmp;
|
||||
num -= 8;
|
||||
}
|
||||
tmp = i << 4;
|
||||
if (tmp != 0) {
|
||||
i = tmp;
|
||||
num -= 4;
|
||||
}
|
||||
tmp = i << 2;
|
||||
if (tmp != 0) {
|
||||
i = tmp;
|
||||
num -= 2;
|
||||
}
|
||||
tmp = i << 1;
|
||||
if (tmp != 0)
|
||||
num--;
|
||||
|
||||
return num;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int recode_wnaf(struct smvt_control *control,
|
||||
/* [nbits/(table_bits + 1) + 3] */
|
||||
const curve448_scalar_t scalar,
|
||||
unsigned int table_bits)
|
||||
{
|
||||
unsigned int table_size = C448_SCALAR_BITS / (table_bits + 1) + 3;
|
||||
int position = table_size - 1; /* at the end */
|
||||
uint64_t current = scalar->limb[0] & 0xFFFF;
|
||||
uint32_t mask = (1 << (table_bits + 1)) - 1;
|
||||
unsigned int w;
|
||||
const unsigned int B_OVER_16 = sizeof(scalar->limb[0]) / 2;
|
||||
unsigned int n, i;
|
||||
|
||||
/* place the end marker */
|
||||
control[position].power = -1;
|
||||
control[position].addend = 0;
|
||||
position--;
|
||||
|
||||
/*
|
||||
* PERF: Could negate scalar if it's large. But then would need more cases
|
||||
* in the actual code that uses it, all for an expected reduction of like
|
||||
* 1/5 op. Probably not worth it.
|
||||
*/
|
||||
|
||||
for (w = 1; w < (C448_SCALAR_BITS - 1) / 16 + 3; w++) {
|
||||
if (w < (C448_SCALAR_BITS - 1) / 16 + 1) {
|
||||
/* Refill the 16 high bits of current */
|
||||
current += (uint32_t)((scalar->limb[w / B_OVER_16]
|
||||
>> (16 * (w % B_OVER_16))) << 16);
|
||||
}
|
||||
|
||||
while (current & 0xFFFF) {
|
||||
uint32_t pos = NUMTRAILINGZEROS((uint32_t)current);
|
||||
uint32_t odd = (uint32_t)current >> pos;
|
||||
int32_t delta = odd & mask;
|
||||
|
||||
assert(position >= 0);
|
||||
if (odd & (1 << (table_bits + 1)))
|
||||
delta -= (1 << (table_bits + 1));
|
||||
current -= delta << pos;
|
||||
control[position].power = pos + 16 * (w - 1);
|
||||
control[position].addend = delta;
|
||||
position--;
|
||||
}
|
||||
current >>= 16;
|
||||
}
|
||||
assert(current == 0);
|
||||
|
||||
position++;
|
||||
n = table_size - position;
|
||||
for (i = 0; i < n; i++)
|
||||
control[i] = control[i + position];
|
||||
|
||||
return n - 1;
|
||||
}
|
||||
|
||||
static void prepare_wnaf_table(pniels_t * output,
|
||||
const curve448_point_t working,
|
||||
unsigned int tbits)
|
||||
{
|
||||
curve448_point_t tmp;
|
||||
int i;
|
||||
pniels_t twop;
|
||||
|
||||
pt_to_pniels(output[0], working);
|
||||
|
||||
if (tbits == 0)
|
||||
return;
|
||||
|
||||
curve448_point_double(tmp, working);
|
||||
pt_to_pniels(twop, tmp);
|
||||
|
||||
add_pniels_to_pt(tmp, output[0], 0);
|
||||
pt_to_pniels(output[1], tmp);
|
||||
|
||||
for (i = 2; i < 1 << tbits; i++) {
|
||||
add_pniels_to_pt(tmp, twop, 0);
|
||||
pt_to_pniels(output[i], tmp);
|
||||
}
|
||||
|
||||
curve448_point_destroy(tmp);
|
||||
OPENSSL_cleanse(twop, sizeof(twop));
|
||||
}
|
||||
|
||||
void curve448_base_double_scalarmul_non_secret(curve448_point_t combo,
|
||||
const curve448_scalar_t scalar1,
|
||||
const curve448_point_t base2,
|
||||
const curve448_scalar_t scalar2)
|
||||
{
|
||||
const int table_bits_var = C448_WNAF_VAR_TABLE_BITS;
|
||||
const int table_bits_pre = C448_WNAF_FIXED_TABLE_BITS;
|
||||
struct smvt_control control_var[C448_SCALAR_BITS /
|
||||
(C448_WNAF_VAR_TABLE_BITS + 1) + 3];
|
||||
struct smvt_control control_pre[C448_SCALAR_BITS /
|
||||
(C448_WNAF_FIXED_TABLE_BITS + 1) + 3];
|
||||
int ncb_pre = recode_wnaf(control_pre, scalar1, table_bits_pre);
|
||||
int ncb_var = recode_wnaf(control_var, scalar2, table_bits_var);
|
||||
pniels_t precmp_var[1 << C448_WNAF_VAR_TABLE_BITS];
|
||||
int contp = 0, contv = 0, i;
|
||||
|
||||
prepare_wnaf_table(precmp_var, base2, table_bits_var);
|
||||
i = control_var[0].power;
|
||||
|
||||
if (i < 0) {
|
||||
curve448_point_copy(combo, curve448_point_identity);
|
||||
return;
|
||||
}
|
||||
if (i > control_pre[0].power) {
|
||||
pniels_to_pt(combo, precmp_var[control_var[0].addend >> 1]);
|
||||
contv++;
|
||||
} else if (i == control_pre[0].power && i >= 0) {
|
||||
pniels_to_pt(combo, precmp_var[control_var[0].addend >> 1]);
|
||||
add_niels_to_pt(combo, curve448_wnaf_base[control_pre[0].addend >> 1],
|
||||
i);
|
||||
contv++;
|
||||
contp++;
|
||||
} else {
|
||||
i = control_pre[0].power;
|
||||
niels_to_pt(combo, curve448_wnaf_base[control_pre[0].addend >> 1]);
|
||||
contp++;
|
||||
}
|
||||
|
||||
for (i--; i >= 0; i--) {
|
||||
int cv = (i == control_var[contv].power);
|
||||
int cp = (i == control_pre[contp].power);
|
||||
|
||||
point_double_internal(combo, combo, i && !(cv || cp));
|
||||
|
||||
if (cv) {
|
||||
assert(control_var[contv].addend);
|
||||
|
||||
if (control_var[contv].addend > 0)
|
||||
add_pniels_to_pt(combo,
|
||||
precmp_var[control_var[contv].addend >> 1],
|
||||
i && !cp);
|
||||
else
|
||||
sub_pniels_from_pt(combo,
|
||||
precmp_var[(-control_var[contv].addend)
|
||||
>> 1], i && !cp);
|
||||
contv++;
|
||||
}
|
||||
|
||||
if (cp) {
|
||||
assert(control_pre[contp].addend);
|
||||
|
||||
if (control_pre[contp].addend > 0)
|
||||
add_niels_to_pt(combo,
|
||||
curve448_wnaf_base[control_pre[contp].addend
|
||||
>> 1], i);
|
||||
else
|
||||
sub_niels_from_pt(combo,
|
||||
curve448_wnaf_base[(-control_pre
|
||||
[contp].addend) >> 1], i);
|
||||
contp++;
|
||||
}
|
||||
}
|
||||
|
||||
/* This function is non-secret, but whatever this is cheap. */
|
||||
OPENSSL_cleanse(control_var, sizeof(control_var));
|
||||
OPENSSL_cleanse(control_pre, sizeof(control_pre));
|
||||
OPENSSL_cleanse(precmp_var, sizeof(precmp_var));
|
||||
|
||||
assert(contv == ncb_var);
|
||||
(void)ncb_var;
|
||||
assert(contp == ncb_pre);
|
||||
(void)ncb_pre;
|
||||
}
|
||||
|
||||
void curve448_point_destroy(curve448_point_t point)
|
||||
{
|
||||
OPENSSL_cleanse(point, sizeof(curve448_point_t));
|
||||
}
|
||||
|
||||
int X448(uint8_t out_shared_key[56], const uint8_t private_key[56],
|
||||
const uint8_t peer_public_value[56])
|
||||
{
|
||||
return x448_int(out_shared_key, peer_public_value, private_key)
|
||||
== C448_SUCCESS;
|
||||
}
|
||||
|
||||
void X448_public_from_private(uint8_t out_public_value[56],
|
||||
const uint8_t private_key[56])
|
||||
{
|
||||
x448_derive_public_key(out_public_value, private_key);
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2017-2018 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
|
||||
*/
|
||||
#ifndef HEADER_CURVE448_LCL_H
|
||||
# define HEADER_CURVE448_LCL_H
|
||||
# include "curve448utils.h"
|
||||
|
||||
int X448(uint8_t out_shared_key[56], const uint8_t private_key[56],
|
||||
const uint8_t peer_public_value[56]);
|
||||
|
||||
void X448_public_from_private(uint8_t out_public_value[56],
|
||||
const uint8_t private_key[56]);
|
||||
|
||||
int ED448_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len,
|
||||
const uint8_t public_key[57], const uint8_t private_key[57],
|
||||
const uint8_t *context, size_t context_len);
|
||||
|
||||
int ED448_verify(const uint8_t *message, size_t message_len,
|
||||
const uint8_t signature[114], const uint8_t public_key[57],
|
||||
const uint8_t *context, size_t context_len);
|
||||
|
||||
int ED448ph_sign(uint8_t *out_sig, const uint8_t hash[64],
|
||||
const uint8_t public_key[57], const uint8_t private_key[57],
|
||||
const uint8_t *context, size_t context_len);
|
||||
|
||||
int ED448ph_verify(const uint8_t hash[64], const uint8_t signature[114],
|
||||
const uint8_t public_key[57], const uint8_t *context,
|
||||
size_t context_len);
|
||||
|
||||
int ED448_public_from_private(uint8_t out_public_key[57],
|
||||
const uint8_t private_key[57]);
|
||||
|
||||
#endif /* HEADER_CURVE448_LCL_H */
|
||||
@@ -0,0 +1,475 @@
|
||||
/*
|
||||
* Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2015-2016 Cryptography Research, 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 Mike Hamburg
|
||||
*/
|
||||
#include "field.h"
|
||||
|
||||
#include "point_448.h"
|
||||
|
||||
static const curve448_precomputed_s curve448_precomputed_base_table = {
|
||||
{
|
||||
{{
|
||||
{FIELD_LITERAL(0x00cc3b062366f4cc,0x003d6e34e314aa3c,0x00d51c0a7521774d,0x0094e060eec6ab8b,0x00d21291b4d80082,0x00befed12b55ef1e,0x00c3dd2df5c94518,0x00e0a7b112b8d4e6)},
|
||||
{FIELD_LITERAL(0x0019eb5608d8723a,0x00d1bab52fb3aedb,0x00270a7311ebc90c,0x0037c12b91be7f13,0x005be16cd8b5c704,0x003e181acda888e1,0x00bc1f00fc3fc6d0,0x00d3839bfa319e20)},
|
||||
{FIELD_LITERAL(0x003caeb88611909f,0x00ea8b378c4df3d4,0x00b3295b95a5a19a,0x00a65f97514bdfb5,0x00b39efba743cab1,0x0016ba98b862fd2d,0x0001508812ee71d7,0x000a75740eea114a)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00ebcf0eb649f823,0x00166d332e98ea03,0x0059ddf64f5cd5f6,0x0047763123d9471b,0x00a64065c53ef62f,0x00978e44c480153d,0x000b5b2a0265f194,0x0046a24b9f32965a)},
|
||||
{FIELD_LITERAL(0x00b9eef787034df0,0x0020bc24de3390cd,0x000022160bae99bb,0x00ae66e886e97946,0x0048d4bbe02cbb8b,0x0072ba97b34e38d4,0x00eae7ec8f03e85a,0x005ba92ecf808b2c)},
|
||||
{FIELD_LITERAL(0x00c9cfbbe74258fd,0x00843a979ea9eaa7,0x000cbb4371cfbe90,0x0059bac8f7f0a628,0x004b3dff882ff530,0x0011869df4d90733,0x00595aa71f4abfc2,0x0070e2d38990c2e6)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00de2010c0a01733,0x00c739a612e24297,0x00a7212643141d7c,0x00f88444f6b67c11,0x00484b7b16ec28f2,0x009c1b8856af9c68,0x00ff4669591fe9d6,0x0054974be08a32c8)},
|
||||
{FIELD_LITERAL(0x0010de3fd682ceed,0x008c07642d83ca4e,0x0013bb064e00a1cc,0x009411ae27870e11,0x00ea8e5b4d531223,0x0032fe7d2aaece2e,0x00d989e243e7bb41,0x000fe79a508e9b8b)},
|
||||
{FIELD_LITERAL(0x005e0426b9bfc5b1,0x0041a5b1d29ee4fa,0x0015b0def7774391,0x00bc164f1f51af01,0x00d543b0942797b9,0x003c129b6398099c,0x002b114c6e5adf18,0x00b4e630e4018a7b)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00d490afc95f8420,0x00b096bf50c1d9b9,0x00799fd707679866,0x007c74d9334afbea,0x00efaa8be80ff4ed,0x0075c4943bb81694,0x00c21c2fca161f36,0x00e77035d492bfee)},
|
||||
{FIELD_LITERAL(0x006658a190dd6661,0x00e0e9bab38609a6,0x0028895c802237ed,0x006a0229c494f587,0x002dcde96c9916b7,0x00d158822de16218,0x00173b917a06856f,0x00ca78a79ae07326)},
|
||||
{FIELD_LITERAL(0x00e35bfc79caced4,0x0087238a3e1fe3bb,0x00bcbf0ff4ceff5b,0x00a19c1c94099b91,0x0071e102b49db976,0x0059e3d004eada1e,0x008da78afa58a47e,0x00579c8ebf269187)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00a16c2905eee75f,0x009d4bcaea2c7e1d,0x00d3bd79bfad19df,0x0050da745193342c,0x006abdb8f6b29ab1,0x00a24fe0a4fef7ef,0x0063730da1057dfb,0x00a08c312c8eb108)},
|
||||
{FIELD_LITERAL(0x00b583be005375be,0x00a40c8f8a4e3df4,0x003fac4a8f5bdbf7,0x00d4481d872cd718,0x004dc8749cdbaefe,0x00cce740d5e5c975,0x000b1c1f4241fd21,0x00a76de1b4e1cd07)},
|
||||
{FIELD_LITERAL(0x007a076500d30b62,0x000a6e117b7f090f,0x00c8712ae7eebd9a,0x000fbd6c1d5f6ff7,0x003a7977246ebf11,0x00166ed969c6600e,0x00aa42e469c98bec,0x00dc58f307cf0666)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x004b491f65a9a28b,0x006a10309e8a55b7,0x00b67210185187ef,0x00cf6497b12d9b8f,0x0085778c56e2b1ba,0x0015b4c07a814d85,0x00686479e62da561,0x008de5d88f114916)},
|
||||
{FIELD_LITERAL(0x00e37c88d6bba7b1,0x003e4577e1b8d433,0x0050d8ea5f510ec0,0x0042fc9f2da9ef59,0x003bd074c1141420,0x00561b8b7b68774e,0x00232e5e5d1013a3,0x006b7f2cb3d7e73f)},
|
||||
{FIELD_LITERAL(0x004bdd0f0b41e6a0,0x001773057c405d24,0x006029f99915bd97,0x006a5ba70a17fe2f,0x0046111977df7e08,0x004d8124c89fb6b7,0x00580983b2bb2724,0x00207bf330d6f3fe)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x007efdc93972a48b,0x002f5e50e78d5fee,0x0080dc11d61c7fe5,0x0065aa598707245b,0x009abba2300641be,0x000c68787656543a,0x00ffe0fef2dc0a17,0x00007ffbd6cb4f3a)},
|
||||
{FIELD_LITERAL(0x0036012f2b836efc,0x00458c126d6b5fbc,0x00a34436d719ad1e,0x0097be6167117dea,0x0009c219c879cff3,0x0065564493e60755,0x00993ac94a8cdec0,0x002d4885a4d0dbaf)},
|
||||
{FIELD_LITERAL(0x00598b60b4c068ba,0x00c547a0be7f1afd,0x009582164acf12af,0x00af4acac4fbbe40,0x005f6ca7c539121a,0x003b6e752ebf9d66,0x00f08a30d5cac5d4,0x00e399bb5f97c5a9)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x007445a0409c0a66,0x00a65c369f3829c0,0x0031d248a4f74826,0x006817f34defbe8e,0x00649741d95ebf2e,0x00d46466ab16b397,0x00fdc35703bee414,0x00343b43334525f8)},
|
||||
{FIELD_LITERAL(0x001796bea93f6401,0x00090c5a42e85269,0x00672412ba1252ed,0x001201d47b6de7de,0x006877bccfe66497,0x00b554fd97a4c161,0x009753f42dbac3cf,0x00e983e3e378270a)},
|
||||
{FIELD_LITERAL(0x00ac3eff18849872,0x00f0eea3bff05690,0x00a6d72c21dd505d,0x001b832642424169,0x00a6813017b540e5,0x00a744bd71b385cd,0x0022a7d089130a7b,0x004edeec9a133486)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00b2d6729196e8a9,0x0088a9bb2031cef4,0x00579e7787dc1567,0x0030f49feb059190,0x00a0b1d69c7f7d8f,0x0040bdcc6d9d806f,0x00d76c4037edd095,0x00bbf24376415dd7)},
|
||||
{FIELD_LITERAL(0x00240465ff5a7197,0x00bb97e76caf27d0,0x004b4edbf8116d39,0x001d8586f708cbaa,0x000f8ee8ff8e4a50,0x00dde5a1945dd622,0x00e6fc1c0957e07c,0x0041c9cdabfd88a0)},
|
||||
{FIELD_LITERAL(0x005344b0bf5b548c,0x002957d0b705cc99,0x00f586a70390553d,0x0075b3229f583cc3,0x00a1aa78227490e4,0x001bf09cf7957717,0x00cf6bf344325f52,0x0065bd1c23ca3ecf)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x009bff3b3239363c,0x00e17368796ef7c0,0x00528b0fe0971f3a,0x0008014fc8d4a095,0x00d09f2e8a521ec4,0x006713ab5dde5987,0x0003015758e0dbb1,0x00215999f1ba212d)},
|
||||
{FIELD_LITERAL(0x002c88e93527da0e,0x0077c78f3456aad5,0x0071087a0a389d1c,0x00934dac1fb96dbd,0x008470e801162697,0x005bc2196cd4ad49,0x00e535601d5087c3,0x00769888700f497f)},
|
||||
{FIELD_LITERAL(0x00da7a4b557298ad,0x0019d2589ea5df76,0x00ef3e38be0c6497,0x00a9644e1312609a,0x004592f61b2558da,0x0082c1df510d7e46,0x0042809a535c0023,0x00215bcb5afd7757)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x002b9df55a1a4213,0x00dcfc3b464a26be,0x00c4f9e07a8144d5,0x00c8e0617a92b602,0x008e3c93accafae0,0x00bf1bcb95b2ca60,0x004ce2426a613bf3,0x00266cac58e40921)},
|
||||
{FIELD_LITERAL(0x008456d5db76e8f0,0x0032ca9cab2ce163,0x0059f2b8bf91abcf,0x0063c2a021712788,0x00f86155af22f72d,0x00db98b2a6c005a0,0x00ac6e416a693ac4,0x007a93572af53226)},
|
||||
{FIELD_LITERAL(0x0087767520f0de22,0x0091f64012279fb5,0x001050f1f0644999,0x004f097a2477ad3c,0x006b37913a9947bd,0x001a3d78645af241,0x0057832bbb3008a7,0x002c1d902b80dc20)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x001a6002bf178877,0x009bce168aa5af50,0x005fc318ff04a7f5,0x0052818f55c36461,0x008768f5d4b24afb,0x0037ffbae7b69c85,0x0018195a4b61edc0,0x001e12ea088434b2)},
|
||||
{FIELD_LITERAL(0x0047d3f804e7ab07,0x00a809ab5f905260,0x00b3ffc7cdaf306d,0x00746e8ec2d6e509,0x00d0dade8887a645,0x00acceeebde0dd37,0x009bc2579054686b,0x0023804f97f1c2bf)},
|
||||
{FIELD_LITERAL(0x0043e2e2e50b80d7,0x00143aafe4427e0f,0x005594aaecab855b,0x008b12ccaaecbc01,0x002deeb091082bc3,0x009cca4be2ae7514,0x00142b96e696d047,0x00ad2a2b1c05256a)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x003914f2f144b78b,0x007a95dd8bee6f68,0x00c7f4384d61c8e6,0x004e51eb60f1bdb2,0x00f64be7aa4621d8,0x006797bfec2f0ac0,0x007d17aab3c75900,0x001893e73cac8bc5)},
|
||||
{FIELD_LITERAL(0x00140360b768665b,0x00b68aca4967f977,0x0001089b66195ae4,0x00fe71122185e725,0x000bca2618d49637,0x00a54f0557d7e98a,0x00cdcd2f91d6f417,0x00ab8c13741fd793)},
|
||||
{FIELD_LITERAL(0x00725ee6b1e549e0,0x007124a0769777fa,0x000b68fdad07ae42,0x0085b909cd4952df,0x0092d2e3c81606f4,0x009f22f6cac099a0,0x00f59da57f2799a8,0x00f06c090122f777)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00ce0bed0a3532bc,0x001a5048a22df16b,0x00e31db4cbad8bf1,0x00e89292120cf00e,0x007d1dd1a9b00034,0x00e2a9041ff8f680,0x006a4c837ae596e7,0x00713af1068070b3)},
|
||||
{FIELD_LITERAL(0x00c4fe64ce66d04b,0x00b095d52e09b3d7,0x00758bbecb1a3a8e,0x00f35cce8d0650c0,0x002b878aa5984473,0x0062e0a3b7544ddc,0x00b25b290ed116fe,0x007b0f6abe0bebf2)},
|
||||
{FIELD_LITERAL(0x0081d4e3addae0a8,0x003410c836c7ffcc,0x00c8129ad89e4314,0x000e3d5a23922dcd,0x00d91e46f29c31f3,0x006c728cde8c5947,0x002bc655ba2566c0,0x002ca94721533108)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x0051e4b3f764d8a9,0x0019792d46e904a0,0x00853bc13dbc8227,0x000840208179f12d,0x0068243474879235,0x0013856fbfe374d0,0x00bda12fe8676424,0x00bbb43635926eb2)},
|
||||
{FIELD_LITERAL(0x0012cdc880a93982,0x003c495b21cd1b58,0x00b7e5c93f22a26e,0x0044aa82dfb99458,0x009ba092cdffe9c0,0x00a14b3ab2083b73,0x000271c2f70e1c4b,0x00eea9cac0f66eb8)},
|
||||
{FIELD_LITERAL(0x001a1847c4ac5480,0x00b1b412935bb03a,0x00f74285983bf2b2,0x00624138b5b5d0f1,0x008820c0b03d38bf,0x00b94e50a18c1572,0x0060f6934841798f,0x00c52f5d66d6ebe2)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00da23d59f9bcea6,0x00e0f27007a06a4b,0x00128b5b43a6758c,0x000cf50190fa8b56,0x00fc877aba2b2d72,0x00623bef52edf53f,0x00e6af6b819669e2,0x00e314dc34fcaa4f)},
|
||||
{FIELD_LITERAL(0x0066e5eddd164d1e,0x00418a7c6fe28238,0x0002e2f37e962c25,0x00f01f56b5975306,0x0048842fa503875c,0x0057b0e968078143,0x00ff683024f3d134,0x0082ae28fcad12e4)},
|
||||
{FIELD_LITERAL(0x0011ddfd21260e42,0x00d05b0319a76892,0x00183ea4368e9b8f,0x00b0815662affc96,0x00b466a5e7ce7c88,0x00db93b07506e6ee,0x0033885f82f62401,0x0086f9090ec9b419)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00d95d1c5fcb435a,0x0016d1ed6b5086f9,0x00792aa0b7e54d71,0x0067b65715f1925d,0x00a219755ec6176b,0x00bc3f026b12c28f,0x00700c897ffeb93e,0x0089b83f6ec50b46)},
|
||||
{FIELD_LITERAL(0x003c97e6384da36e,0x00423d53eac81a09,0x00b70d68f3cdce35,0x00ee7959b354b92c,0x00f4e9718819c8ca,0x009349f12acbffe9,0x005aee7b62cb7da6,0x00d97764154ffc86)},
|
||||
{FIELD_LITERAL(0x00526324babb46dc,0x002ee99b38d7bf9e,0x007ea51794706ef4,0x00abeb04da6e3c39,0x006b457c1d281060,0x00fe243e9a66c793,0x00378de0fb6c6ee4,0x003e4194b9c3cb93)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00fed3cd80ca2292,0x0015b043a73ca613,0x000a9fd7bf9be227,0x003b5e03de2db983,0x005af72d46904ef7,0x00c0f1b5c49faa99,0x00dc86fc3bd305e1,0x00c92f08c1cb1797)},
|
||||
{FIELD_LITERAL(0x0079680ce111ed3b,0x001a1ed82806122c,0x000c2e7466d15df3,0x002c407f6f7150fd,0x00c5e7c96b1b0ce3,0x009aa44626863ff9,0x00887b8b5b80be42,0x00b6023cec964825)},
|
||||
{FIELD_LITERAL(0x00e4a8e1048970c8,0x0062887b7830a302,0x00bcf1c8cd81402b,0x0056dbb81a68f5be,0x0014eced83f12452,0x00139e1a510150df,0x00bb81140a82d1a3,0x000febcc1aaf1aa7)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00a7527958238159,0x0013ec9537a84cd6,0x001d7fee7d562525,0x00b9eefa6191d5e5,0x00dbc97db70bcb8a,0x00481affc7a4d395,0x006f73d3e70c31bb,0x00183f324ed96a61)},
|
||||
{FIELD_LITERAL(0x0039dd7ce7fc6860,0x00d64f6425653da1,0x003e037c7f57d0af,0x0063477a06e2bcf2,0x001727dbb7ac67e6,0x0049589f5efafe2e,0x00fc0fef2e813d54,0x008baa5d087fb50d)},
|
||||
{FIELD_LITERAL(0x0024fb59d9b457c7,0x00a7d4e060223e4c,0x00c118d1b555fd80,0x0082e216c732f22a,0x00cd2a2993089504,0x003638e836a3e13d,0x000d855ee89b4729,0x008ec5b7d4810c91)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x001bf51f7d65cdfd,0x00d14cdafa16a97d,0x002c38e60fcd10e7,0x00a27446e393efbd,0x000b5d8946a71fdd,0x0063df2cde128f2f,0x006c8679569b1888,0x0059ffc4925d732d)},
|
||||
{FIELD_LITERAL(0x00ece96f95f2b66f,0x00ece7952813a27b,0x0026fc36592e489e,0x007157d1a2de0f66,0x00759dc111d86ddf,0x0012881e5780bb0f,0x00c8ccc83ad29496,0x0012b9bd1929eb71)},
|
||||
{FIELD_LITERAL(0x000fa15a20da5df0,0x00349ddb1a46cd31,0x002c512ad1d8e726,0x00047611f669318d,0x009e68fba591e17e,0x004320dffa803906,0x00a640874951a3d3,0x00b6353478baa24f)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x009696510000d333,0x00ec2f788bc04826,0x000e4d02b1f67ba5,0x00659aa8dace08b6,0x00d7a38a3a3ae533,0x008856defa8c746b,0x004d7a4402d3da1a,0x00ea82e06229260f)},
|
||||
{FIELD_LITERAL(0x006a15bb20f75c0c,0x0079a144027a5d0c,0x00d19116ce0b4d70,0x0059b83bcb0b268e,0x005f58f63f16c127,0x0079958318ee2c37,0x00defbb063d07f82,0x00f1f0b931d2d446)},
|
||||
{FIELD_LITERAL(0x00cb5e4c3c35d422,0x008df885ca43577f,0x00fa50b16ca3e471,0x005a0e58e17488c8,0x00b2ceccd6d34d19,0x00f01d5d235e36e9,0x00db2e7e4be6ca44,0x00260ab77f35fccd)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x006f6fd9baac61d5,0x002a7710a020a895,0x009de0db7fc03d4d,0x00cdedcb1875f40b,0x00050caf9b6b1e22,0x005e3a6654456ab0,0x00775fdf8c4423d4,0x0028701ea5738b5d)},
|
||||
{FIELD_LITERAL(0x009ffd90abfeae96,0x00cba3c2b624a516,0x005ef08bcee46c91,0x00e6fde30afb6185,0x00f0b4db4f818ce4,0x006c54f45d2127f5,0x00040125035854c7,0x00372658a3287e13)},
|
||||
{FIELD_LITERAL(0x00d7070fb1beb2ab,0x0078fc845a93896b,0x006894a4b2f224a6,0x005bdd8192b9dbde,0x00b38839874b3a9e,0x00f93618b04b7a57,0x003e3ec75fd2c67e,0x00bf5e6bfc29494a)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00f19224ebba2aa5,0x0074f89d358e694d,0x00eea486597135ad,0x0081579a4555c7e1,0x0010b9b872930a9d,0x00f002e87a30ecc0,0x009b9d66b6de56e2,0x00a3c4f45e8004eb)},
|
||||
{FIELD_LITERAL(0x0045e8dda9400888,0x002ff12e5fc05db7,0x00a7098d54afe69c,0x00cdbe846a500585,0x00879c1593ca1882,0x003f7a7fea76c8b0,0x002cd73dd0c8e0a1,0x00645d6ce96f51fe)},
|
||||
{FIELD_LITERAL(0x002b7e83e123d6d6,0x00398346f7419c80,0x0042922e55940163,0x005e7fc5601886a3,0x00e88f2cee1d3103,0x00e7fab135f2e377,0x00b059984dbf0ded,0x0009ce080faa5bb8)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x0085e78af7758979,0x00275a4ee1631a3a,0x00d26bc0ed78b683,0x004f8355ea21064f,0x00d618e1a32696e5,0x008d8d7b150e5680,0x00a74cd854b278d2,0x001dd62702203ea0)},
|
||||
{FIELD_LITERAL(0x00f89335c2a59286,0x00a0f5c905d55141,0x00b41fb836ee9382,0x00e235d51730ca43,0x00a5cb37b5c0a69a,0x009b966ffe136c45,0x00cb2ea10bf80ed1,0x00fb2b370b40dc35)},
|
||||
{FIELD_LITERAL(0x00d687d16d4ee8ba,0x0071520bdd069dff,0x00de85c60d32355d,0x0087d2e3565102f4,0x00cde391b8dfc9aa,0x00e18d69efdfefe5,0x004a9d0591954e91,0x00fa36dd8b50eee5)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x002e788749a865f7,0x006e4dc3116861ea,0x009f1428c37276e6,0x00e7d2e0fc1e1226,0x003aeebc6b6c45f6,0x0071a8073bf500c9,0x004b22ad986b530c,0x00f439e63c0d79d4)},
|
||||
{FIELD_LITERAL(0x006bc3d53011f470,0x00032d6e692b83e8,0x00059722f497cd0b,0x0009b4e6f0c497cc,0x0058a804b7cce6c0,0x002b71d3302bbd5d,0x00e2f82a36765fce,0x008dded99524c703)},
|
||||
{FIELD_LITERAL(0x004d058953747d64,0x00701940fe79aa6f,0x00a620ac71c760bf,0x009532b611158b75,0x00547ed7f466f300,0x003cb5ab53a8401a,0x00c7763168ce3120,0x007e48e33e4b9ab2)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x001b2fc57bf3c738,0x006a3f918993fb80,0x0026f7a14fdec288,0x0075a2cdccef08db,0x00d3ecbc9eecdbf1,0x0048c40f06e5bf7f,0x00d63e423009896b,0x000598bc99c056a8)},
|
||||
{FIELD_LITERAL(0x002f194eaafa46dc,0x008e38f57fe87613,0x00dc8e5ae25f4ab2,0x000a17809575e6bd,0x00d3ec7923ba366a,0x003a7e72e0ad75e3,0x0010024b88436e0a,0x00ed3c5444b64051)},
|
||||
{FIELD_LITERAL(0x00831fc1340af342,0x00c9645669466d35,0x007692b4cc5a080f,0x009fd4a47ac9259f,0x001eeddf7d45928b,0x003c0446fc45f28b,0x002c0713aa3e2507,0x0095706935f0f41e)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00766ae4190ec6d8,0x0065768cabc71380,0x00b902598416cdc2,0x00380021ad38df52,0x008f0b89d6551134,0x004254d4cc62c5a5,0x000d79f4484b9b94,0x00b516732ae3c50e)},
|
||||
{FIELD_LITERAL(0x001fb73475c45509,0x00d2b2e5ea43345a,0x00cb3c3842077bd1,0x0029f90ad820946e,0x007c11b2380778aa,0x009e54ece62c1704,0x004bc60c41ca01c3,0x004525679a5a0b03)},
|
||||
{FIELD_LITERAL(0x00c64fbddbed87b3,0x0040601d11731faa,0x009c22475b6f9d67,0x0024b79dae875f15,0x00616fed3f02c3b0,0x0000cf39f6af2d3b,0x00c46bac0aa9a688,0x00ab23e2800da204)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x000b3a37617632b0,0x00597199fe1cfb6c,0x0042a7ccdfeafdd6,0x004cc9f15ebcea17,0x00f436e596a6b4a4,0x00168861142df0d8,0x000753edfec26af5,0x000c495d7e388116)},
|
||||
{FIELD_LITERAL(0x0017085f4a346148,0x00c7cf7a37f62272,0x001776e129bc5c30,0x009955134c9eef2a,0x001ba5bdf1df07be,0x00ec39497103a55c,0x006578354fda6cfb,0x005f02719d4f15ee)},
|
||||
{FIELD_LITERAL(0x0052b9d9b5d9655d,0x00d4ec7ba1b461c3,0x00f95df4974f280b,0x003d8e5ca11aeb51,0x00d4981eb5a70b26,0x000af9a4f6659f29,0x004598c846faeb43,0x0049d9a183a47670)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x000a72d23dcb3f1f,0x00a3737f84011727,0x00f870c0fbbf4a47,0x00a7aadd04b5c9ca,0x000c7715c67bd072,0x00015a136afcd74e,0x0080d5caea499634,0x0026b448ec7514b7)},
|
||||
{FIELD_LITERAL(0x00b60167d9e7d065,0x00e60ba0d07381e8,0x003a4f17b725c2d4,0x006c19fe176b64fa,0x003b57b31af86ccb,0x0021047c286180fd,0x00bdc8fb00c6dbb6,0x00fe4a9f4bab4f3f)},
|
||||
{FIELD_LITERAL(0x0088ffc3a16111f7,0x009155e4245d0bc8,0x00851d68220572d5,0x00557ace1e514d29,0x0031d7c339d91022,0x00101d0ae2eaceea,0x00246ab3f837b66a,0x00d5216d381ff530)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x0057e7ea35f36dae,0x00f47d7ad15de22e,0x00d757ea4b105115,0x008311457d579d7e,0x00b49b75b1edd4eb,0x0081c7ff742fd63a,0x00ddda3187433df6,0x00475727d55f9c66)},
|
||||
{FIELD_LITERAL(0x00a6295218dc136a,0x00563b3af0e9c012,0x00d3753b0145db1b,0x004550389c043dc1,0x00ea94ae27401bdf,0x002b0b949f2b7956,0x00c63f780ad8e23c,0x00e591c47d6bab15)},
|
||||
{FIELD_LITERAL(0x00416c582b058eb6,0x004107da5b2cc695,0x00b3cd2556aeec64,0x00c0b418267e57a1,0x001799293579bd2e,0x0046ed44590e4d07,0x001d7459b3630a1e,0x00c6afba8b6696aa)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x008d6009b26da3f8,0x00898e88ca06b1ca,0x00edb22b2ed7fe62,0x00fbc93516aabe80,0x008b4b470c42ce0d,0x00e0032ba7d0dcbb,0x00d76da3a956ecc8,0x007f20fe74e3852a)},
|
||||
{FIELD_LITERAL(0x002419222c607674,0x00a7f23af89188b3,0x00ad127284e73d1c,0x008bba582fae1c51,0x00fc6aa7ca9ecab1,0x003df5319eb6c2ba,0x002a05af8a8b199a,0x004bf8354558407c)},
|
||||
{FIELD_LITERAL(0x00ce7d4a30f0fcbf,0x00d02c272629f03d,0x0048c001f7400bc2,0x002c21368011958d,0x0098a550391e96b5,0x002d80b66390f379,0x001fa878760cc785,0x001adfce54b613d5)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x001ed4dc71fa2523,0x005d0bff19bf9b5c,0x00c3801cee065a64,0x001ed0b504323fbf,0x0003ab9fdcbbc593,0x00df82070178b8d2,0x00a2bcaa9c251f85,0x00c628a3674bd02e)},
|
||||
{FIELD_LITERAL(0x006b7a0674f9f8de,0x00a742414e5c7cff,0x0041cbf3c6e13221,0x00e3a64fd207af24,0x0087c05f15fbe8d1,0x004c50936d9e8a33,0x001306ec21042b6d,0x00a4f4137d1141c2)},
|
||||
{FIELD_LITERAL(0x0009e6fb921568b0,0x00b3c60120219118,0x002a6c3460dd503a,0x009db1ef11654b54,0x0063e4bf0be79601,0x00670d34bb2592b9,0x00dcee2f6c4130ce,0x00b2682e88e77f54)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x000d5b4b3da135ab,0x00838f3e5064d81d,0x00d44eb50f6d94ed,0x0008931ab502ac6d,0x00debe01ca3d3586,0x0025c206775f0641,0x005ad4b6ae912763,0x007e2c318ad8f247)},
|
||||
{FIELD_LITERAL(0x00ddbe0750dd1add,0x004b3c7b885844b8,0x00363e7ecf12f1ae,0x0062e953e6438f9d,0x0023cc73b076afe9,0x00b09fa083b4da32,0x00c7c3d2456c541d,0x005b591ec6b694d4)},
|
||||
{FIELD_LITERAL(0x0028656e19d62fcf,0x0052a4af03df148d,0x00122765ddd14e42,0x00f2252904f67157,0x004741965b636f3a,0x006441d296132cb9,0x005e2106f956a5b7,0x00247029592d335c)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x003fe038eb92f894,0x000e6da1b72e8e32,0x003a1411bfcbe0fa,0x00b55d473164a9e4,0x00b9a775ac2df48d,0x0002ddf350659e21,0x00a279a69eb19cb3,0x00f844eab25cba44)},
|
||||
{FIELD_LITERAL(0x00c41d1f9c1f1ac1,0x007b2df4e9f19146,0x00b469355fd5ba7a,0x00b5e1965afc852a,0x00388d5f1e2d8217,0x0022079e4c09ae93,0x0014268acd4ef518,0x00c1dd8d9640464c)},
|
||||
{FIELD_LITERAL(0x0038526adeed0c55,0x00dd68c607e3fe85,0x00f746ddd48a5d57,0x0042f2952b963b7c,0x001cbbd6876d5ec2,0x005e341470bca5c2,0x00871d41e085f413,0x00e53ab098f45732)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x004d51124797c831,0x008f5ae3750347ad,0x0070ced94c1a0c8e,0x00f6db2043898e64,0x000d00c9a5750cd0,0x000741ec59bad712,0x003c9d11aab37b7f,0x00a67ba169807714)},
|
||||
{FIELD_LITERAL(0x00adb2c1566e8b8f,0x0096c68a35771a9a,0x00869933356f334a,0x00ba9c93459f5962,0x009ec73fb6e8ca4b,0x003c3802c27202e1,0x0031f5b733e0c008,0x00f9058c19611fa9)},
|
||||
{FIELD_LITERAL(0x00238f01814a3421,0x00c325a44b6cce28,0x002136f97aeb0e73,0x000cac8268a4afe2,0x0022fd218da471b3,0x009dcd8dfff8def9,0x00cb9f8181d999bb,0x00143ae56edea349)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x0000623bf87622c5,0x00a1966fdd069496,0x00c315b7b812f9fc,0x00bdf5efcd128b97,0x001d464f532e3e16,0x003cd94f081bfd7e,0x00ed9dae12ce4009,0x002756f5736eee70)},
|
||||
{FIELD_LITERAL(0x00a5187e6ee7341b,0x00e6d52e82d83b6e,0x00df3c41323094a7,0x00b3324f444e9de9,0x00689eb21a35bfe5,0x00f16363becd548d,0x00e187cc98e7f60f,0x00127d9062f0ccab)},
|
||||
{FIELD_LITERAL(0x004ad71b31c29e40,0x00a5fcace12fae29,0x004425b5597280ed,0x00e7ef5d716c3346,0x0010b53ada410ac8,0x0092310226060c9b,0x0091c26128729c7e,0x0088b42900f8ec3b)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00f1e26e9762d4a8,0x00d9d74082183414,0x00ffec9bd57a0282,0x000919e128fd497a,0x00ab7ae7d00fe5f8,0x0054dc442851ff68,0x00c9ebeb3b861687,0x00507f7cab8b698f)},
|
||||
{FIELD_LITERAL(0x00c13c5aae3ae341,0x009c6c9ed98373e7,0x00098f26864577a8,0x0015b886e9488b45,0x0037692c42aadba5,0x00b83170b8e7791c,0x001670952ece1b44,0x00fd932a39276da2)},
|
||||
{FIELD_LITERAL(0x0081a3259bef3398,0x005480fff416107b,0x00ce4f607d21be98,0x003ffc084b41df9b,0x0043d0bb100502d1,0x00ec35f575ba3261,0x00ca18f677300ef3,0x00e8bb0a827d8548)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00df76b3328ada72,0x002e20621604a7c2,0x00f910638a105b09,0x00ef4724d96ef2cd,0x00377d83d6b8a2f7,0x00b4f48805ade324,0x001cd5da8b152018,0x0045af671a20ca7f)},
|
||||
{FIELD_LITERAL(0x009ae3b93a56c404,0x004a410b7a456699,0x00023a619355e6b2,0x009cdc7297387257,0x0055b94d4ae70d04,0x002cbd607f65b005,0x003208b489697166,0x00ea2aa058867370)},
|
||||
{FIELD_LITERAL(0x00f29d2598ee3f32,0x00b4ac5385d82adc,0x007633eaf04df19b,0x00aa2d3d77ceab01,0x004a2302fcbb778a,0x00927f225d5afa34,0x004a8e9d5047f237,0x008224ae9dbce530)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x001cf640859b02f8,0x00758d1d5d5ce427,0x00763c784ef4604c,0x005fa81aee205270,0x00ac537bfdfc44cb,0x004b919bd342d670,0x00238508d9bf4b7a,0x00154888795644f3)},
|
||||
{FIELD_LITERAL(0x00c845923c084294,0x00072419a201bc25,0x0045f408b5f8e669,0x00e9d6a186b74dfe,0x00e19108c68fa075,0x0017b91d874177b7,0x002f0ca2c7912c5a,0x009400aa385a90a2)},
|
||||
{FIELD_LITERAL(0x0071110b01482184,0x00cfed0044f2bef8,0x0034f2901cf4662e,0x003b4ae2a67f9834,0x00cca9b96fe94810,0x00522507ae77abd0,0x00bac7422721e73e,0x0066622b0f3a62b0)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00f8ac5cf4705b6a,0x00867d82dcb457e3,0x007e13ab2ccc2ce9,0x009ee9a018d3930e,0x008370f8ecb42df8,0x002d9f019add263e,0x003302385b92d196,0x00a15654536e2c0c)},
|
||||
{FIELD_LITERAL(0x0026ef1614e160af,0x00c023f9edfc9c76,0x00cff090da5f57ba,0x0076db7a66643ae9,0x0019462f8c646999,0x008fec00b3854b22,0x00d55041692a0a1c,0x0065db894215ca00)},
|
||||
{FIELD_LITERAL(0x00a925036e0a451c,0x002a0390c36b6cc1,0x00f27020d90894f4,0x008d90d52cbd3d7f,0x00e1d0137392f3b8,0x00f017c158b51a8f,0x00cac313d3ed7dbc,0x00b99a81e3eb42d3)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00b54850275fe626,0x0053a3fd1ec71140,0x00e3d2d7dbe096fa,0x00e4ac7b595cce4c,0x0077bad449c0a494,0x00b7c98814afd5b3,0x0057226f58486cf9,0x00b1557154f0cc57)},
|
||||
{FIELD_LITERAL(0x008cc9cd236315c0,0x0031d9c5b39fda54,0x00a5713ef37e1171,0x00293d5ae2886325,0x00c4aba3e05015e1,0x0003f35ef78e4fc6,0x0039d6bd3ac1527b,0x0019d7c3afb77106)},
|
||||
{FIELD_LITERAL(0x007b162931a985af,0x00ad40a2e0daa713,0x006df27c4009f118,0x00503e9f4e2e8bec,0x00751a77c82c182d,0x000298937769245b,0x00ffb1e8fabf9ee5,0x0008334706e09abe)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00dbca4e98a7dcd9,0x00ee29cfc78bde99,0x00e4a3b6995f52e9,0x0045d70189ae8096,0x00fd2a8a3b9b0d1b,0x00af1793b107d8e1,0x00dbf92cbe4afa20,0x00da60f798e3681d)},
|
||||
{FIELD_LITERAL(0x004246bfcecc627a,0x004ba431246c03a4,0x00bd1d101872d497,0x003b73d3f185ee16,0x001feb2e2678c0e3,0x00ff13c5a89dec76,0x00ed06042e771d8f,0x00a4fd2a897a83dd)},
|
||||
{FIELD_LITERAL(0x009a4a3be50d6597,0x00de3165fc5a1096,0x004f3f56e345b0c7,0x00f7bf721d5ab8bc,0x004313e47b098c50,0x00e4c7d5c0e1adbb,0x002e3e3db365051e,0x00a480c2cd6a96fb)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00417fa30a7119ed,0x00af257758419751,0x00d358a487b463d4,0x0089703cc720b00d,0x00ce56314ff7f271,0x0064db171ade62c1,0x00640b36d4a22fed,0x00424eb88696d23f)},
|
||||
{FIELD_LITERAL(0x004ede34af2813f3,0x00d4a8e11c9e8216,0x004796d5041de8a5,0x00c4c6b4d21cc987,0x00e8a433ee07fa1e,0x0055720b5abcc5a1,0x008873ea9c74b080,0x005b3fec1ab65d48)},
|
||||
{FIELD_LITERAL(0x0047e5277db70ec5,0x000a096c66db7d6b,0x00b4164cc1730159,0x004a9f783fe720fe,0x00a8177b94449dbc,0x0095a24ff49a599f,0x0069c1c578250cbc,0x00452019213debf4)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x0021ce99e09ebda3,0x00fcbd9f91875ad0,0x009bbf6b7b7a0b5f,0x00388886a69b1940,0x00926a56d0f81f12,0x00e12903c3358d46,0x005dfce4e8e1ce9d,0x0044cfa94e2f7e23)},
|
||||
{FIELD_LITERAL(0x001bd59c09e982ea,0x00f72daeb937b289,0x0018b76dca908e0e,0x00edb498512384ad,0x00ce0243b6cc9538,0x00f96ff690cb4e70,0x007c77bf9f673c8d,0x005bf704c088a528)},
|
||||
{FIELD_LITERAL(0x0093d4628dcb33be,0x0095263d51d42582,0x0049b3222458fe06,0x00e7fce73b653a7f,0x003ca2ebce60b369,0x00c5de239a32bea4,0x0063b8b3d71fb6bf,0x0039aeeb78a1a839)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x007dc52da400336c,0x001fded1e15b9457,0x00902e00f5568e3a,0x00219bef40456d2d,0x005684161fb3dbc9,0x004a4e9be49a76ea,0x006e685ae88b78ff,0x0021c42f13042d3c)},
|
||||
{FIELD_LITERAL(0x00fb22bb5fd3ce50,0x0017b48aada7ae54,0x00fd5c44ad19a536,0x000ccc4e4e55e45c,0x00fd637d45b4c3f5,0x0038914e023c37cf,0x00ac1881d6a8d898,0x00611ed8d3d943a8)},
|
||||
{FIELD_LITERAL(0x0056e2259d113d2b,0x00594819b284ec16,0x00c7bf794bb36696,0x00721ee75097cdc6,0x00f71be9047a2892,0x00df6ba142564edf,0x0069580b7a184e8d,0x00f056e38fca0fee)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x009df98566a18c6d,0x00cf3a200968f219,0x0044ba60da6d9086,0x00dbc9c0e344da03,0x000f9401c4466855,0x00d46a57c5b0a8d1,0x00875a635d7ac7c6,0x00ef4a933b7e0ae6)},
|
||||
{FIELD_LITERAL(0x005e8694077a1535,0x008bef75f71c8f1d,0x000a7c1316423511,0x00906e1d70604320,0x003fc46c1a2ffbd6,0x00d1d5022e68f360,0x002515fba37bbf46,0x00ca16234e023b44)},
|
||||
{FIELD_LITERAL(0x00787c99561f4690,0x00a857a8c1561f27,0x00a10df9223c09fe,0x00b98a9562e3b154,0x004330b8744c3ed2,0x00e06812807ec5c4,0x00e4cf6a7db9f1e3,0x00d95b089f132a34)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x002922b39ca33eec,0x0090d12a5f3ab194,0x00ab60c02fb5f8ed,0x00188d292abba1cf,0x00e10edec9698f6e,0x0069a4d9934133c8,0x0024aac40e6d3d06,0x001702c2177661b0)},
|
||||
{FIELD_LITERAL(0x00139078397030bd,0x000e3c447e859a00,0x0064a5b334c82393,0x00b8aabeb7358093,0x00020778bb9ae73b,0x0032ee94c7892a18,0x008215253cb41bda,0x005e2797593517ae)},
|
||||
{FIELD_LITERAL(0x0083765a5f855d4a,0x0051b6d1351b8ee2,0x00116de548b0f7bb,0x0087bd88703affa0,0x0095b2cc34d7fdd2,0x0084cd81b53f0bc8,0x008562fc995350ed,0x00a39abb193651e3)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x0019e23f0474b114,0x00eb94c2ad3b437e,0x006ddb34683b75ac,0x00391f9209b564c6,0x00083b3bb3bff7aa,0x00eedcd0f6dceefc,0x00b50817f794fe01,0x0036474deaaa75c9)},
|
||||
{FIELD_LITERAL(0x0091868594265aa2,0x00797accae98ca6d,0x0008d8c5f0f8a184,0x00d1f4f1c2b2fe6e,0x0036783dfb48a006,0x008c165120503527,0x0025fd780058ce9b,0x0068beb007be7d27)},
|
||||
{FIELD_LITERAL(0x00d0ff88aa7c90c2,0x00b2c60dacf53394,0x0094a7284d9666d6,0x00bed9022ce7a19d,0x00c51553f0cd7682,0x00c3fb870b124992,0x008d0bc539956c9b,0x00fc8cf258bb8885)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x003667bf998406f8,0x0000115c43a12975,0x001e662f3b20e8fd,0x0019ffa534cb24eb,0x00016be0dc8efb45,0x00ff76a8b26243f5,0x00ae20d241a541e3,0x0069bd6af13cd430)},
|
||||
{FIELD_LITERAL(0x0045fdc16487cda3,0x00b2d8e844cf2ed7,0x00612c50e88c1607,0x00a08aabc66c1672,0x006031fdcbb24d97,0x001b639525744b93,0x004409d62639ab17,0x00a1853d0347ab1d)},
|
||||
{FIELD_LITERAL(0x0075a1a56ebf5c21,0x00a3e72be9ac53ed,0x00efcde1629170c2,0x0004225fe91ef535,0x0088049fc73dfda7,0x004abc74857e1288,0x0024e2434657317c,0x00d98cb3d3e5543c)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00b4b53eab6bdb19,0x009b22d8b43711d0,0x00d948b9d961785d,0x00cb167b6f279ead,0x00191de3a678e1c9,0x00d9dd9511095c2e,0x00f284324cd43067,0x00ed74fa535151dd)},
|
||||
{FIELD_LITERAL(0x007e32c049b5c477,0x009d2bfdbd9bcfd8,0x00636e93045938c6,0x007fde4af7687298,0x0046a5184fafa5d3,0x0079b1e7f13a359b,0x00875adf1fb927d6,0x00333e21c61bcad2)},
|
||||
{FIELD_LITERAL(0x00048014f73d8b8d,0x0075684aa0966388,0x0092be7df06dc47c,0x0097cebcd0f5568a,0x005a7004d9c4c6a9,0x00b0ecbb659924c7,0x00d90332dd492a7c,0x0057fc14df11493d)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x0008ed8ea0ad95be,0x0041d324b9709645,0x00e25412257a19b4,0x0058df9f3423d8d2,0x00a9ab20def71304,0x009ae0dbf8ac4a81,0x00c9565977e4392a,0x003c9269444baf55)},
|
||||
{FIELD_LITERAL(0x007df6cbb926830b,0x00d336058ae37865,0x007af47dac696423,0x0048d3011ec64ac8,0x006b87666e40049f,0x0036a2e0e51303d7,0x00ba319bd79dbc55,0x003e2737ecc94f53)},
|
||||
{FIELD_LITERAL(0x00d296ff726272d9,0x00f6d097928fcf57,0x00e0e616a55d7013,0x00deaf454ed9eac7,0x0073a56bedef4d92,0x006ccfdf6fc92e19,0x009d1ee1371a7218,0x00ee3c2ee4462d80)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00437bce9bccdf9d,0x00e0c8e2f85dc0a3,0x00c91a7073995a19,0x00856ec9fe294559,0x009e4b33394b156e,0x00e245b0dc497e5c,0x006a54e687eeaeff,0x00f1cd1cd00fdb7c)},
|
||||
{FIELD_LITERAL(0x008132ae5c5d8cd1,0x00121d68324a1d9f,0x00d6be9dafcb8c76,0x00684d9070edf745,0x00519fbc96d7448e,0x00388182fdc1f27e,0x000235baed41f158,0x00bf6cf6f1a1796a)},
|
||||
{FIELD_LITERAL(0x002adc4b4d148219,0x003084ada0d3a90a,0x0046de8aab0f2e4e,0x00452d342a67b5fd,0x00d4b50f01d4de21,0x00db6d9fc0cefb79,0x008c184c86a462cd,0x00e17c83764d42da)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x007b2743b9a1e01a,0x007847ffd42688c4,0x006c7844d610a316,0x00f0cb8b250aa4b0,0x00a19060143b3ae6,0x0014eb10b77cfd80,0x000170905729dd06,0x00063b5b9cd72477)},
|
||||
{FIELD_LITERAL(0x00ce382dc7993d92,0x00021153e938b4c8,0x00096f7567f48f51,0x0058f81ddfe4b0d5,0x00cc379a56b355c7,0x002c760770d3e819,0x00ee22d1d26e5a40,0x00de6d93d5b082d7)},
|
||||
{FIELD_LITERAL(0x000a91a42c52e056,0x00185f6b77fce7ea,0x000803c51962f6b5,0x0022528582ba563d,0x0043f8040e9856d6,0x0085a29ec81fb860,0x005f9a611549f5ff,0x00c1f974ecbd4b06)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x005b64c6fd65ec97,0x00c1fdd7f877bc7f,0x000d9cc6c89f841c,0x005c97b7f1aff9ad,0x0075e3c61475d47e,0x001ecb1ba8153011,0x00fe7f1c8d71d40d,0x003fa9757a229832)},
|
||||
{FIELD_LITERAL(0x00ffc5c89d2b0cba,0x00d363d42e3e6fc3,0x0019a1a0118e2e8a,0x00f7baeff48882e1,0x001bd5af28c6b514,0x0055476ca2253cb2,0x00d8eb1977e2ddf3,0x00b173b1adb228a1)},
|
||||
{FIELD_LITERAL(0x00f2cb99dd0ad707,0x00e1e08b6859ddd8,0x000008f2d0650bcc,0x00d7ed392f8615c3,0x00976750a94da27f,0x003e83bb0ecb69ba,0x00df8e8d15c14ac6,0x00f9f7174295d9c2)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00f11cc8e0e70bcb,0x00e5dc689974e7dd,0x0014e409f9ee5870,0x00826e6689acbd63,0x008a6f4e3d895d88,0x00b26a8da41fd4ad,0x000fb7723f83efd7,0x009c749db0a5f6c3)},
|
||||
{FIELD_LITERAL(0x002389319450f9ba,0x003677f31aa1250a,0x0092c3db642f38cb,0x00f8b64c0dfc9773,0x00cd49fe3505b795,0x0068105a4090a510,0x00df0ba2072a8bb6,0x00eb396143afd8be)},
|
||||
{FIELD_LITERAL(0x00a0d4ecfb24cdff,0x00ddaf8008ba6479,0x00f0b3e36d4b0f44,0x003734bd3af1f146,0x00b87e2efc75527e,0x00d230df55ddab50,0x002613257ae56c1d,0x00bc0946d135934d)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00468711bd994651,0x0033108fa67561bf,0x0089d760192a54b4,0x00adc433de9f1871,0x000467d05f36e050,0x007847e0f0579f7f,0x00a2314ad320052d,0x00b3a93649f0b243)},
|
||||
{FIELD_LITERAL(0x0067f8f0c4fe26c9,0x0079c4a3cc8f67b9,0x0082b1e62f23550d,0x00f2d409caefd7f5,0x0080e67dcdb26e81,0x0087ae993ea1f98a,0x00aa108becf61d03,0x001acf11efb608a3)},
|
||||
{FIELD_LITERAL(0x008225febbab50d9,0x00f3b605e4dd2083,0x00a32b28189e23d2,0x00d507e5e5eb4c97,0x005a1a84e302821f,0x0006f54c1c5f08c7,0x00a347c8cb2843f0,0x0009f73e9544bfa5)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x006c59c9ae744185,0x009fc32f1b4282cd,0x004d6348ca59b1ac,0x00105376881be067,0x00af4096013147dc,0x004abfb5a5cb3124,0x000d2a7f8626c354,0x009c6ed568e07431)},
|
||||
{FIELD_LITERAL(0x00e828333c297f8b,0x009ef3cf8c3f7e1f,0x00ab45f8fff31cb9,0x00c8b4178cb0b013,0x00d0c50dd3260a3f,0x0097126ac257f5bc,0x0042376cc90c705a,0x001d96fdb4a1071e)},
|
||||
{FIELD_LITERAL(0x00542d44d89ee1a8,0x00306642e0442d98,0x0090853872b87338,0x002362cbf22dc044,0x002c222adff663b8,0x0067c924495fcb79,0x000e621d983c977c,0x00df77a9eccb66fb)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x002809e4bbf1814a,0x00b9e854f9fafb32,0x00d35e67c10f7a67,0x008f1bcb76e748cf,0x004224d9515687d2,0x005ba0b774e620c4,0x00b5e57db5d54119,0x00e15babe5683282)},
|
||||
{FIELD_LITERAL(0x00832d02369b482c,0x00cba52ff0d93450,0x003fa9c908d554db,0x008d1e357b54122f,0x00abd91c2dc950c6,0x007eff1df4c0ec69,0x003f6aeb13fb2d31,0x00002d6179fc5b2c)},
|
||||
{FIELD_LITERAL(0x0046c9eda81c9c89,0x00b60cb71c8f62fc,0x0022f5a683baa558,0x00f87319fccdf997,0x009ca09b51ce6a22,0x005b12baf4af7d77,0x008a46524a1e33e2,0x00035a77e988be0d)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00a7efe46a7dbe2f,0x002f66fd55014fe7,0x006a428afa1ff026,0x0056caaa9604ab72,0x0033f3bcd7fac8ae,0x00ccb1aa01c86764,0x00158d1edf13bf40,0x009848ee76fcf3b4)},
|
||||
{FIELD_LITERAL(0x00a9e7730a819691,0x00d9cc73c4992b70,0x00e299bde067de5a,0x008c314eb705192a,0x00e7226f17e8a3cc,0x0029dfd956e65a47,0x0053a8e839073b12,0x006f942b2ab1597e)},
|
||||
{FIELD_LITERAL(0x001c3d780ecd5e39,0x0094f247fbdcc5fe,0x00d5c786fd527764,0x00b6f4da74f0db2a,0x0080f1f8badcd5fc,0x00f36a373ad2e23b,0x00f804f9f4343bf2,0x00d1af40ec623982)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x0082aeace5f1b144,0x00f68b3108cf4dd3,0x00634af01dde3020,0x000beab5df5c2355,0x00e8b790d1b49b0b,0x00e48d15854e36f4,0x0040ab2d95f3db9f,0x002711c4ed9e899a)},
|
||||
{FIELD_LITERAL(0x0039343746531ebe,0x00c8509d835d429d,0x00e79eceff6b0018,0x004abfd31e8efce5,0x007bbfaaa1e20210,0x00e3be89c193e179,0x001c420f4c31d585,0x00f414a315bef5ae)},
|
||||
{FIELD_LITERAL(0x007c296a24990df8,0x00d5d07525a75588,0x00dd8e113e94b7e7,0x007bbc58febe0cc8,0x0029f51af9bfcad3,0x007e9311ec7ab6f3,0x009a884de1676343,0x0050d5f2dce84be9)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x005fa020cca2450a,0x00491c29db6416d8,0x0037cefe3f9f9a85,0x003d405230647066,0x0049e835f0fdbe89,0x00feb78ac1a0815c,0x00828e4b32dc9724,0x00db84f2dc8d6fd4)},
|
||||
{FIELD_LITERAL(0x0098cddc8b39549a,0x006da37e3b05d22c,0x00ce633cfd4eb3cb,0x00fda288ef526acd,0x0025338878c5d30a,0x00f34438c4e5a1b4,0x00584efea7c310f1,0x0041a551f1b660ad)},
|
||||
{FIELD_LITERAL(0x00d7f7a8fbd6437a,0x0062872413bf3753,0x00ad4bbcb43c584b,0x007fe49be601d7e3,0x0077c659789babf4,0x00eb45fcb06a741b,0x005ce244913f9708,0x0088426401736326)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x007bf562ca768d7c,0x006c1f3a174e387c,0x00f024b447fee939,0x007e7af75f01143f,0x003adb70b4eed89d,0x00e43544021ad79a,0x0091f7f7042011f6,0x0093c1a1ee3a0ddc)},
|
||||
{FIELD_LITERAL(0x00a0b68ec1eb72d2,0x002c03235c0d45a0,0x00553627323fe8c5,0x006186e94b17af94,0x00a9906196e29f14,0x0025b3aee6567733,0x007e0dd840080517,0x0018eb5801a4ba93)},
|
||||
{FIELD_LITERAL(0x00d7fe7017bf6a40,0x006e3f0624be0c42,0x00ffbba205358245,0x00f9fc2cf8194239,0x008d93b37bf15b4e,0x006ddf2e38be8e95,0x002b6e79bf5fcff9,0x00ab355da425e2de)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00938f97e20be973,0x0099141a36aaf306,0x0057b0ca29e545a1,0x0085db571f9fbc13,0x008b333c554b4693,0x0043ab6ef3e241cb,0x0054fb20aa1e5c70,0x00be0ff852760adf)},
|
||||
{FIELD_LITERAL(0x003973d8938971d6,0x002aca26fa80c1f5,0x00108af1faa6b513,0x00daae275d7924e6,0x0053634ced721308,0x00d2355fe0bbd443,0x00357612b2d22095,0x00f9bb9dd4136cf3)},
|
||||
{FIELD_LITERAL(0x002bff12cf5e03a5,0x001bdb1fa8a19cf8,0x00c91c6793f84d39,0x00f869f1b2eba9af,0x0059bc547dc3236b,0x00d91611d6d38689,0x00e062daaa2c0214,0x00ed3c047cc2bc82)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x000050d70c32b31a,0x001939d576d437b3,0x00d709e598bf9fe6,0x00a885b34bd2ee9e,0x00dd4b5c08ab1a50,0x0091bebd50b55639,0x00cf79ff64acdbc6,0x006067a39d826336)},
|
||||
{FIELD_LITERAL(0x0062dd0fb31be374,0x00fcc96b84c8e727,0x003f64f1375e6ae3,0x0057d9b6dd1af004,0x00d6a167b1103c7b,0x00dd28f3180fb537,0x004ff27ad7167128,0x008934c33461f2ac)},
|
||||
{FIELD_LITERAL(0x0065b472b7900043,0x00ba7efd2ff1064b,0x000b67d6c4c3020f,0x0012d28469f4e46d,0x0031c32939703ec7,0x00b49f0bce133066,0x00f7e10416181d47,0x005c90f51867eecc)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x0051207abd179101,0x00fc2a5c20d9c5da,0x00fb9d5f2701b6df,0x002dd040fdea82b8,0x00f163b0738442ff,0x00d9736bd68855b8,0x00e0d8e93005e61c,0x00df5a40b3988570)},
|
||||
{FIELD_LITERAL(0x0006918f5dfce6dc,0x00d4bf1c793c57fb,0x0069a3f649435364,0x00e89a50e5b0cd6e,0x00b9f6a237e973af,0x006d4ed8b104e41d,0x00498946a3924cd2,0x00c136ec5ac9d4f7)},
|
||||
{FIELD_LITERAL(0x0011a9c290ac5336,0x002b9a2d4a6a6533,0x009a8a68c445d937,0x00361b27b07e5e5c,0x003c043b1755b974,0x00b7eb66cf1155ee,0x0077af5909eefff2,0x0098f609877cc806)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00ab13af436bf8f4,0x000bcf0a0dac8574,0x00d50c864f705045,0x00c40e611debc842,0x0085010489bd5caa,0x007c5050acec026f,0x00f67d943c8da6d1,0x00de1da0278074c6)},
|
||||
{FIELD_LITERAL(0x00b373076597455f,0x00e83f1af53ac0f5,0x0041f63c01dc6840,0x0097dea19b0c6f4b,0x007f9d63b4c1572c,0x00e692d492d0f5f0,0x00cbcb392e83b4ad,0x0069c0f39ed9b1a8)},
|
||||
{FIELD_LITERAL(0x00861030012707c9,0x009fbbdc7fd4aafb,0x008f591d6b554822,0x00df08a41ea18ade,0x009d7d83e642abea,0x0098c71bda3b78ff,0x0022c89e7021f005,0x0044d29a3fe1e3c4)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00e748cd7b5c52f2,0x00ea9df883f89cc3,0x0018970df156b6c7,0x00c5a46c2a33a847,0x00cbde395e32aa09,0x0072474ebb423140,0x00fb00053086a23d,0x001dafcfe22d4e1f)},
|
||||
{FIELD_LITERAL(0x00c903ee6d825540,0x00add6c4cf98473e,0x007636efed4227f1,0x00905124ae55e772,0x00e6b38fab12ed53,0x0045e132b863fe55,0x003974662edb366a,0x00b1787052be8208)},
|
||||
{FIELD_LITERAL(0x00a614b00d775c7c,0x00d7c78941cc7754,0x00422dd68b5dabc4,0x00a6110f0167d28b,0x00685a309c252886,0x00b439ffd5143660,0x003656e29ee7396f,0x00c7c9b9ed5ad854)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x0040f7e7c5b37bf2,0x0064e4dc81181bba,0x00a8767ae2a366b6,0x001496b4f90546f2,0x002a28493f860441,0x0021f59513049a3a,0x00852d369a8b7ee3,0x00dd2e7d8b7d30a9)},
|
||||
{FIELD_LITERAL(0x00006e34a35d9fbc,0x00eee4e48b2f019a,0x006b344743003a5f,0x00541d514f04a7e3,0x00e81f9ee7647455,0x005e2b916c438f81,0x00116f8137b7eff0,0x009bd3decc7039d1)},
|
||||
{FIELD_LITERAL(0x0005d226f434110d,0x00af8288b8ef21d5,0x004a7a52ef181c8c,0x00be0b781b4b06de,0x00e6e3627ded07e1,0x00e43aa342272b8b,0x00e86ab424577d84,0x00fb292c566e35bb)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00334f5303ea1222,0x00dfb3dbeb0a5d3e,0x002940d9592335c1,0x00706a7a63e8938a,0x005a533558bc4caf,0x00558e33192022a9,0x00970d9faf74c133,0x002979fcb63493ca)},
|
||||
{FIELD_LITERAL(0x00e38abece3c82ab,0x005a51f18a2c7a86,0x009dafa2e86d592e,0x00495a62eb688678,0x00b79df74c0eb212,0x0023e8cc78b75982,0x005998cb91075e13,0x00735aa9ba61bc76)},
|
||||
{FIELD_LITERAL(0x00d9f7a82ddbe628,0x00a1fc782889ae0f,0x0071ffda12d14b66,0x0037cf4eca7fb3d5,0x00c80bc242c58808,0x0075bf8c2d08c863,0x008d41f31afc52a7,0x00197962ecf38741)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x006e9f475cccf2ee,0x00454b9cd506430c,0x00224a4fb79ee479,0x0062e3347ef0b5e2,0x0034fd2a3512232a,0x00b8b3cb0f457046,0x00eb20165daa38ec,0x00128eebc2d9c0f7)},
|
||||
{FIELD_LITERAL(0x00bfc5fa1e4ea21f,0x00c21d7b6bb892e6,0x00cf043f3acf0291,0x00c13f2f849b3c90,0x00d1a97ebef10891,0x0061e130a445e7fe,0x0019513fdedbf22b,0x001d60c813bff841)},
|
||||
{FIELD_LITERAL(0x0019561c7fcf0213,0x00e3dca6843ebd77,0x0068ea95b9ca920e,0x009bdfb70f253595,0x00c68f59186aa02a,0x005aee1cca1c3039,0x00ab79a8a937a1ce,0x00b9a0e549959e6f)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00c79e0b6d97dfbd,0x00917c71fd2bc6e8,0x00db7529ccfb63d8,0x00be5be957f17866,0x00a9e11fdc2cdac1,0x007b91a8e1f44443,0x00a3065e4057d80f,0x004825f5b8d5f6d4)},
|
||||
{FIELD_LITERAL(0x003e4964fa8a8fc8,0x00f6a1cdbcf41689,0x00943cb18fe7fda7,0x00606dafbf34440a,0x005d37a86399c789,0x00e79a2a69417403,0x00fe34f7e68b8866,0x0011f448ed2df10e)},
|
||||
{FIELD_LITERAL(0x00f1f57efcc1fcc4,0x00513679117de154,0x002e5b5b7c86d8c3,0x009f6486561f9cfb,0x00169e74b0170cf7,0x00900205af4af696,0x006acfddb77853f3,0x00df184c90f31068)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00b37396c3320791,0x00fc7b67175c5783,0x00c36d2cd73ecc38,0x0080ebcc0b328fc5,0x0043a5b22b35d35d,0x00466c9f1713c9da,0x0026ad346dcaa8da,0x007c684e701183a6)},
|
||||
{FIELD_LITERAL(0x00fd579ffb691713,0x00b76af4f81c412d,0x00f239de96110f82,0x00e965fb437f0306,0x00ca7e9436900921,0x00e487f1325fa24a,0x00633907de476380,0x00721c62ac5b8ea0)},
|
||||
{FIELD_LITERAL(0x00c0d54e542eb4f9,0x004ed657171c8dcf,0x00b743a4f7c2a39b,0x00fd9f93ed6cc567,0x00307fae3113e58b,0x0058aa577c93c319,0x00d254556f35b346,0x00491aada2203f0d)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00dff3103786ff34,0x000144553b1f20c3,0x0095613baeb930e4,0x00098058275ea5d4,0x007cd1402b046756,0x0074d74e4d58aee3,0x005f93fc343ff69b,0x00873df17296b3b0)},
|
||||
{FIELD_LITERAL(0x00c4a1fb48635413,0x00b5dd54423ad59f,0x009ff5d53fd24a88,0x003c98d267fc06a7,0x002db7cb20013641,0x00bd1d6716e191f2,0x006dbc8b29094241,0x0044bbf233dafa2c)},
|
||||
{FIELD_LITERAL(0x0055838d41f531e6,0x00bf6a2dd03c81b2,0x005827a061c4839e,0x0000de2cbb36aac3,0x002efa29d9717478,0x00f9e928cc8a77ba,0x00c134b458def9ef,0x00958a182223fc48)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x000a9ee23c06881f,0x002c727d3d871945,0x00f47d971512d24a,0x00671e816f9ef31a,0x00883af2cfaad673,0x00601f98583d6c9a,0x00b435f5adc79655,0x00ad87b71c04bff2)},
|
||||
{FIELD_LITERAL(0x007860d99db787cf,0x00fda8983018f4a8,0x008c8866bac4743c,0x00ef471f84c82a3f,0x00abea5976d3b8e7,0x00714882896cd015,0x00b49fae584ddac5,0x008e33a1a0b69c81)},
|
||||
{FIELD_LITERAL(0x007b6ee2c9e8a9ec,0x002455dbbd89d622,0x006490cf4eaab038,0x00d925f6c3081561,0x00153b3047de7382,0x003b421f8bdceb6f,0x00761a4a5049da78,0x00980348c5202433)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x007f8a43da97dd5c,0x00058539c800fc7b,0x0040f3cf5a28414a,0x00d68dd0d95283d6,0x004adce9da90146e,0x00befa41c7d4f908,0x007603bc2e3c3060,0x00bdf360ab3545db)},
|
||||
{FIELD_LITERAL(0x00eebfd4e2312cc3,0x00474b2564e4fc8c,0x003303ef14b1da9b,0x003c93e0e66beb1d,0x0013619b0566925a,0x008817c24d901bf3,0x00b62bd8898d218b,0x0075a7716f1e88a2)},
|
||||
{FIELD_LITERAL(0x0009218da1e6890f,0x0026907f5fd02575,0x004dabed5f19d605,0x003abf181870249d,0x00b52fd048cc92c4,0x00b6dd51e415a5c5,0x00d9eb82bd2b4014,0x002c865a43b46b43)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x0070047189452f4c,0x00f7ad12e1ce78d5,0x00af1ba51ec44a8b,0x005f39f63e667cd6,0x00058eac4648425e,0x00d7fdab42bea03b,0x0028576a5688de15,0x00af973209e77c10)},
|
||||
{FIELD_LITERAL(0x00c338b915d8fef0,0x00a893292045c39a,0x0028ab4f2eba6887,0x0060743cb519fd61,0x0006213964093ac0,0x007c0b7a43f6266d,0x008e3557c4fa5bda,0x002da976de7b8d9d)},
|
||||
{FIELD_LITERAL(0x0048729f8a8b6dcd,0x00fe23b85cc4d323,0x00e7384d16e4db0e,0x004a423970678942,0x00ec0b763345d4ba,0x00c477b9f99ed721,0x00c29dad3777b230,0x001c517b466f7df6)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x006366c380f7b574,0x001c7d1f09ff0438,0x003e20a7301f5b22,0x00d3efb1916d28f6,0x0049f4f81060ce83,0x00c69d91ea43ced1,0x002b6f3e5cd269ed,0x005b0fb22ce9ec65)},
|
||||
{FIELD_LITERAL(0x00aa2261022d883f,0x00ebcca4548010ac,0x002528512e28a437,0x0070ca7676b66082,0x0084bda170f7c6d3,0x00581b4747c9b8bb,0x005c96a01061c7e2,0x00fb7c4a362b5273)},
|
||||
{FIELD_LITERAL(0x00c30020eb512d02,0x0060f288283a4d26,0x00b7ed13becde260,0x0075ebb74220f6e9,0x00701079fcfe8a1f,0x001c28fcdff58938,0x002e4544b8f4df6b,0x0060c5bc4f1a7d73)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00ae307cf069f701,0x005859f222dd618b,0x00212d6c46ec0b0d,0x00a0fe4642afb62d,0x00420d8e4a0a8903,0x00a80ff639bdf7b0,0x0019bee1490b5d8e,0x007439e4b9c27a86)},
|
||||
{FIELD_LITERAL(0x00a94700032a093f,0x0076e96c225216e7,0x00a63a4316e45f91,0x007d8bbb4645d3b2,0x00340a6ff22793eb,0x006f935d4572aeb7,0x00b1fb69f00afa28,0x009e8f3423161ed3)},
|
||||
{FIELD_LITERAL(0x009ef49c6b5ced17,0x00a555e6269e9f0a,0x007e6f1d79ec73b5,0x009ac78695a32ac4,0x0001d77fbbcd5682,0x008cea1fee0aaeed,0x00f42bea82a53462,0x002e46ab96cafcc9)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x0051cfcc5885377a,0x00dce566cb1803ca,0x00430c7643f2c7d4,0x00dce1a1337bdcc0,0x0010d5bd7283c128,0x003b1b547f9b46fe,0x000f245e37e770ab,0x007b72511f022b37)},
|
||||
{FIELD_LITERAL(0x0060db815bc4786c,0x006fab25beedc434,0x00c610d06084797c,0x000c48f08537bec0,0x0031aba51c5b93da,0x007968fa6e01f347,0x0030070da52840c6,0x00c043c225a4837f)},
|
||||
{FIELD_LITERAL(0x001bcfd00649ee93,0x006dceb47e2a0fd5,0x00f2cebda0cf8fd0,0x00b6b9d9d1fbdec3,0x00815262e6490611,0x00ef7f5ce3176760,0x00e49cd0c998d58b,0x005fc6cc269ba57c)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x008940211aa0d633,0x00addae28136571d,0x00d68fdbba20d673,0x003bc6129bc9e21a,0x000346cf184ebe9a,0x0068774d741ebc7f,0x0019d5e9e6966557,0x0003cbd7f981b651)},
|
||||
{FIELD_LITERAL(0x004a2902926f8d3f,0x00ad79b42637ab75,0x0088f60b90f2d4e8,0x0030f54ef0e398c4,0x00021dc9bf99681e,0x007ebf66fde74ee3,0x004ade654386e9a4,0x00e7485066be4c27)},
|
||||
{FIELD_LITERAL(0x00445f1263983be0,0x004cf371dda45e6a,0x00744a89d5a310e7,0x001f20ce4f904833,0x00e746edebe66e29,0x000912ab1f6c153d,0x00f61d77d9b2444c,0x0001499cd6647610)},
|
||||
}}
|
||||
}
|
||||
};
|
||||
const struct curve448_precomputed_s *curve448_precomputed_base
|
||||
= &curve448_precomputed_base_table;
|
||||
|
||||
static const niels_t curve448_wnaf_base_table[32] = {
|
||||
{{
|
||||
{FIELD_LITERAL(0x00303cda6feea532,0x00860f1d5a3850e4,0x00226b9fa4728ccd,0x00e822938a0a0c0c,0x00263a61c9ea9216,0x001204029321b828,0x006a468360983c65,0x0002846f0a782143)},
|
||||
{FIELD_LITERAL(0x00303cda6feea532,0x00860f1d5a3850e4,0x00226b9fa4728ccd,0x006822938a0a0c0c,0x00263a61c9ea9215,0x001204029321b828,0x006a468360983c65,0x0082846f0a782143)},
|
||||
{FIELD_LITERAL(0x00ef8e22b275198d,0x00b0eb141a0b0e8b,0x001f6789da3cb38c,0x006d2ff8ed39073e,0x00610bdb69a167f3,0x00571f306c9689b4,0x00f557e6f84b2df8,0x002affd38b2c86db)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00cea0fc8d2e88b5,0x00821612d69f1862,0x0074c283b3e67522,0x005a195ba05a876d,0x000cddfe557feea4,0x008046c795bcc5e5,0x00540969f4d6e119,0x00d27f96d6b143d5)},
|
||||
{FIELD_LITERAL(0x000c3b1019d474e8,0x00e19533e4952284,0x00cc9810ba7c920a,0x00f103d2785945ac,0x00bfa5696cc69b34,0x00a8d3d51e9ca839,0x005623cb459586b9,0x00eae7ce1cd52e9e)},
|
||||
{FIELD_LITERAL(0x0005a178751dd7d8,0x002cc3844c69c42f,0x00acbfe5efe10539,0x009c20f43431a65a,0x008435d96374a7b3,0x009ee57566877bd3,0x0044691725ed4757,0x001e87bb2fe2c6b2)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x000cedc4debf7a04,0x002ffa45000470ac,0x002e9f9678201915,0x0017da1208c4fe72,0x007d558cc7d656cb,0x0037a827287cf289,0x00142472d3441819,0x009c21f166cf8dd1)},
|
||||
{FIELD_LITERAL(0x003ef83af164b2f2,0x000949a5a0525d0d,0x00f4498186cac051,0x00e77ac09ef126d2,0x0073ae0b2c9296e9,0x001c163f6922e3ed,0x0062946159321bea,0x00cfb79b22990b39)},
|
||||
{FIELD_LITERAL(0x00b001431ca9e654,0x002d7e5eabcc9a3a,0x0052e8114c2f6747,0x0079ac4f94487f92,0x00bffd919b5d749c,0x00261f92ad15e620,0x00718397b7a97895,0x00c1443e6ebbc0c4)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00eacd90c1e0a049,0x008977935b149fbe,0x0004cb9ba11c93dc,0x009fbd5b3470844d,0x004bc18c9bfc22cf,0x0057679a991839f3,0x00ef15b76fb4092e,0x0074a5173a225041)},
|
||||
{FIELD_LITERAL(0x003f5f9d7ec4777b,0x00ab2e733c919c94,0x001bb6c035245ae5,0x00a325a49a883630,0x0033e9a9ea3cea2f,0x00e442a1eaa0e844,0x00b2116d5b0e71b8,0x00c16abed6d64047)},
|
||||
{FIELD_LITERAL(0x00c560b5ed051165,0x001945adc5d65094,0x00e221865710f910,0x00cc12bc9e9b8ceb,0x004faa9518914e35,0x0017476d89d42f6d,0x00b8f637c8fa1c8b,0x0088c7d2790864b8)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00ef7eafc1c69be6,0x0085d3855778fbea,0x002c8d5b450cb6f5,0x004e77de5e1e7fec,0x0047c057893abded,0x001b430b85d51e16,0x00965c7b45640c3c,0x00487b2bb1162b97)},
|
||||
{FIELD_LITERAL(0x0099c73a311beec2,0x00a3eff38d8912ad,0x002efa9d1d7e8972,0x00f717ae1e14d126,0x002833f795850c8b,0x0066c12ad71486bd,0x00ae9889da4820eb,0x00d6044309555c08)},
|
||||
{FIELD_LITERAL(0x004b1c5283d15e41,0x00669d8ea308ff75,0x0004390233f762a1,0x00e1d67b83cb6cec,0x003eebaa964c78b1,0x006b0aff965eb664,0x00b313d4470bdc37,0x008814ffcb3cb9d8)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x009724b8ce68db70,0x007678b5ed006f3d,0x00bdf4b89c0abd73,0x00299748e04c7c6d,0x00ddd86492c3c977,0x00c5a7febfa30a99,0x00ed84715b4b02bb,0x00319568adf70486)},
|
||||
{FIELD_LITERAL(0x0070ff2d864de5bb,0x005a37eeb637ee95,0x0033741c258de160,0x00e6ca5cb1988f46,0x001ceabd92a24661,0x0030957bd500fe40,0x001c3362afe912c5,0x005187889f678bd2)},
|
||||
{FIELD_LITERAL(0x0086835fc62bbdc7,0x009c3516ca4910a1,0x00956c71f8d00783,0x0095c78fcf63235f,0x00fc7ff6ba05c222,0x00cdd8b3f8d74a52,0x00ac5ae16de8256e,0x00e9d4be8ed48624)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00c0ce11405df2d8,0x004e3f37b293d7b6,0x002410172e1ac6db,0x00b8dbff4bf8143d,0x003a7b409d56eb66,0x003e0f6a0dfef9af,0x0081c4e4d3645be1,0x00ce76076b127623)},
|
||||
{FIELD_LITERAL(0x00f6ee0f98974239,0x0042d89af07d3a4f,0x00846b7fe84346b5,0x006a21fc6a8d39a1,0x00ac8bc2541ff2d9,0x006d4e2a77732732,0x009a39b694cc3f2f,0x0085c0aa2a404c8f)},
|
||||
{FIELD_LITERAL(0x00b261101a218548,0x00c1cae96424277b,0x00869da0a77dd268,0x00bc0b09f8ec83ea,0x00d61027f8e82ba9,0x00aa4c85999dce67,0x00eac3132b9f3fe1,0x00fb9b0cf1c695d2)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x0043079295512f0d,0x0046a009861758e0,0x003ee2842a807378,0x0034cc9d1298e4fa,0x009744eb4d31b3ee,0x00afacec96650cd0,0x00ac891b313761ae,0x00e864d6d26e708a)},
|
||||
{FIELD_LITERAL(0x00a84d7c8a23b491,0x0088e19aa868b27f,0x0005986d43e78ce9,0x00f28012f0606d28,0x0017ded7e10249b3,0x005ed4084b23af9b,0x00b9b0a940564472,0x00ad9056cceeb1f4)},
|
||||
{FIELD_LITERAL(0x00db91b357fe755e,0x00a1aa544b15359c,0x00af4931a0195574,0x007686124fe11aef,0x00d1ead3c7b9ef7e,0x00aaf5fc580f8c15,0x00e727be147ee1ec,0x003c61c1e1577b86)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x009d3fca983220cf,0x00cd11acbc853dc4,0x0017590409d27f1d,0x00d2176698082802,0x00fa01251b2838c8,0x00dd297a0d9b51c6,0x00d76c92c045820a,0x00534bc7c46c9033)},
|
||||
{FIELD_LITERAL(0x0080ed9bc9b07338,0x00fceac7745d2652,0x008a9d55f5f2cc69,0x0096ce72df301ac5,0x00f53232e7974d87,0x0071728c7ae73947,0x0090507602570778,0x00cb81cfd883b1b2)},
|
||||
{FIELD_LITERAL(0x005011aadea373da,0x003a8578ec896034,0x00f20a6535fa6d71,0x005152d31e5a87cf,0x002bac1c8e68ca31,0x00b0e323db4c1381,0x00f1d596b7d5ae25,0x00eae458097cb4e0)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00920ac80f9b0d21,0x00f80f7f73401246,0x0086d37849b557d6,0x0002bd4b317b752e,0x00b26463993a42bb,0x002070422a73b129,0x00341acaa0380cb3,0x00541914dd66a1b2)},
|
||||
{FIELD_LITERAL(0x00c1513cd66abe8c,0x000139e01118944d,0x0064abbcb8080bbb,0x00b3b08202473142,0x00c629ef25da2403,0x00f0aec3310d9b7f,0x0050b2227472d8cd,0x00f6c8a922d41fb4)},
|
||||
{FIELD_LITERAL(0x001075ccf26b7b1f,0x00bb6bb213170433,0x00e9491ad262da79,0x009ef4f48d2d384c,0x008992770766f09d,0x001584396b6b1101,0x00af3f8676c9feef,0x0024603c40269118)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x009dd7b31319527c,0x001e7ac948d873a9,0x00fa54b46ef9673a,0x0066efb8d5b02fe6,0x00754b1d3928aeae,0x0004262ac72a6f6b,0x0079b7d49a6eb026,0x003126a753540102)},
|
||||
{FIELD_LITERAL(0x009666e24f693947,0x00f714311269d45f,0x0010ffac1d0c851c,0x0066e80c37363497,0x00f1f4ad010c60b0,0x0015c87408470ff7,0x00651d5e9c7766a4,0x008138819d7116de)},
|
||||
{FIELD_LITERAL(0x003934b11c57253b,0x00ef308edf21f46e,0x00e54e99c7a16198,0x0080d57135764e63,0x00751c27b946bc24,0x00dd389ce4e9e129,0x00a1a2bfd1cd84dc,0x002fae73e5149b32)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00911657dffb4cdd,0x00c100b7cc553d06,0x00449d075ec467cc,0x007062100bc64e70,0x0043cf86f7bd21e7,0x00f401dc4b797dea,0x005224afb2f62e65,0x00d1ede3fb5a42be)},
|
||||
{FIELD_LITERAL(0x00f2ba36a41aa144,0x00a0c22d946ee18f,0x008aae8ef9a14f99,0x00eef4d79b19bb36,0x008e75ce3d27b1fc,0x00a65daa03b29a27,0x00d9cc83684eb145,0x009e1ed80cc2ed74)},
|
||||
{FIELD_LITERAL(0x00bed953d1997988,0x00b93ed175a24128,0x00871c5963fb6365,0x00ca2df20014a787,0x00f5d9c1d0b34322,0x00f6f5942818db0a,0x004cc091f49c9906,0x00e8a188a60bff9f)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x0032c7762032fae8,0x00e4087232e0bc21,0x00f767344b6e8d85,0x00bbf369b76c2aa2,0x008a1f46c6e1570c,0x001368cd9780369f,0x007359a39d079430,0x0003646512921434)},
|
||||
{FIELD_LITERAL(0x007c4b47ca7c73e7,0x005396221039734b,0x008b64ddf0e45d7e,0x00bfad5af285e6c2,0x008ec711c5b1a1a8,0x00cf663301237f98,0x00917ee3f1655126,0x004152f337efedd8)},
|
||||
{FIELD_LITERAL(0x0007c7edc9305daa,0x000a6664f273701c,0x00f6e78795e200b1,0x005d05b9ecd2473e,0x0014f5f17c865786,0x00c7fd2d166fa995,0x004939a2d8eb80e0,0x002244ba0942c199)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00321e767f0262cf,0x002e57d776caf68e,0x00bf2c94814f0437,0x00c339196acd622f,0x001db4cce71e2770,0x001ded5ddba6eee2,0x0078608ab1554c8d,0x00067fe0ab76365b)},
|
||||
{FIELD_LITERAL(0x00f09758e11e3985,0x00169efdbd64fad3,0x00e8889b7d6dacd6,0x0035cdd58ea88209,0x00bcda47586d7f49,0x003cdddcb2879088,0x0016da70187e954b,0x009556ea2e92aacd)},
|
||||
{FIELD_LITERAL(0x008cab16bd1ff897,0x00b389972cdf753f,0x00ea8ed1e46dfdc0,0x004fe7ef94c589f4,0x002b8ae9b805ecf3,0x0025c08d892874a5,0x0023938e98d44c4c,0x00f759134cabf69c)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x006c2a84678e4b3b,0x007a194aacd1868f,0x00ed0225af424761,0x00da0a6f293c64b8,0x001062ac5c6a7a18,0x0030f5775a8aeef4,0x0002acaad76b7af0,0x00410b8fd63a579f)},
|
||||
{FIELD_LITERAL(0x001ec59db3d9590e,0x001e9e3f1c3f182d,0x0045a9c3ec2cab14,0x0008198572aeb673,0x00773b74068bd167,0x0012535eaa395434,0x0044dba9e3bbb74a,0x002fba4d3c74bd0e)},
|
||||
{FIELD_LITERAL(0x0042bf08fe66922c,0x003318b8fbb49e8c,0x00d75946004aa14c,0x00f601586b42bf1c,0x00c74cf1d912fe66,0x00abcb36974b30ad,0x007eb78720c9d2b8,0x009f54ab7bd4df85)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00db9fc948f73826,0x00fa8b3746ed8ee9,0x00132cb65aafbeb2,0x00c36ff3fe7925b8,0x00837daed353d2fe,0x00ec661be0667cf4,0x005beb8ed2e90204,0x00d77dd69e564967)},
|
||||
{FIELD_LITERAL(0x0042e6268b861751,0x0008dd0469500c16,0x00b51b57c338a3fd,0x00cc4497d85cff6b,0x002f13d6b57c34a4,0x0083652eaf301105,0x00cc344294cc93a8,0x0060f4d02810e270)},
|
||||
{FIELD_LITERAL(0x00a8954363cd518b,0x00ad171124bccb7b,0x0065f46a4adaae00,0x001b1a5b2a96e500,0x0043fe24f8233285,0x0066996d8ae1f2c3,0x00c530f3264169f9,0x00c0f92d07cf6a57)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x0036a55c6815d943,0x008c8d1def993db3,0x002e0e1e8ff7318f,0x00d883a4b92db00a,0x002f5e781ae33906,0x001a72adb235c06d,0x00f2e59e736e9caa,0x001a4b58e3031914)},
|
||||
{FIELD_LITERAL(0x00d73bfae5e00844,0x00bf459766fb5f52,0x0061b4f5a5313cde,0x004392d4c3b95514,0x000d3551b1077523,0x0000998840ee5d71,0x006de6e340448b7b,0x00251aa504875d6e)},
|
||||
{FIELD_LITERAL(0x003bf343427ac342,0x00adc0a78642b8c5,0x0003b893175a8314,0x0061a34ade5703bc,0x00ea3ea8bb71d632,0x00be0df9a1f198c2,0x0046dd8e7c1635fb,0x00f1523fdd25d5e5)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00633f63fc9dd406,0x00e713ff80e04a43,0x0060c6e970f2d621,0x00a57cd7f0df1891,0x00f2406a550650bb,0x00b064290efdc684,0x001eab0144d17916,0x00cd15f863c293ab)},
|
||||
{FIELD_LITERAL(0x0029cec55273f70d,0x007044ee275c6340,0x0040f637a93015e2,0x00338bb78db5aae9,0x001491b2a6132147,0x00a125d6cfe6bde3,0x005f7ac561ba8669,0x001d5eaea3fbaacf)},
|
||||
{FIELD_LITERAL(0x00054e9635e3be31,0x000e43f31e2872be,0x00d05b1c9e339841,0x006fac50bd81fd98,0x00cdc7852eaebb09,0x004ff519b061991b,0x009099e8107d4c85,0x00273e24c36a4a61)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00070b4441ef2c46,0x00efa5b02801a109,0x00bf0b8c3ee64adf,0x008a67e0b3452e98,0x001916b1f2fa7a74,0x00d781a78ff6cdc3,0x008682ce57e5c919,0x00cc1109dd210da3)},
|
||||
{FIELD_LITERAL(0x00cae8aaff388663,0x005e983a35dda1c7,0x007ab1030d8e37f4,0x00e48940f5d032fe,0x006a36f9ef30b331,0x009be6f03958c757,0x0086231ceba91400,0x008bd0f7b823e7aa)},
|
||||
{FIELD_LITERAL(0x00cf881ebef5a45a,0x004ebea78e7c6f2c,0x0090da9209cf26a0,0x00de2b2e4c775b84,0x0071d6031c3c15ae,0x00d9e927ef177d70,0x00894ee8c23896fd,0x00e3b3b401e41aad)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00204fef26864170,0x00819269c5dee0f8,0x00bfb4713ec97966,0x0026339a6f34df78,0x001f26e64c761dc2,0x00effe3af313cb60,0x00e17b70138f601b,0x00f16e1ccd9ede5e)},
|
||||
{FIELD_LITERAL(0x005d9a8353fdb2db,0x0055cc2048c698f0,0x00f6c4ac89657218,0x00525034d73faeb2,0x00435776fbda3c7d,0x0070ea5312323cbc,0x007a105d44d069fb,0x006dbc8d6dc786aa)},
|
||||
{FIELD_LITERAL(0x0017cff19cd394ec,0x00fef7b810922587,0x00e6483970dff548,0x00ddf36ad6874264,0x00e61778523fcce2,0x0093a66c0c93b24a,0x00fd367114db7f86,0x007652d7ddce26dd)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00d92ced7ba12843,0x00aea9c7771e86e7,0x0046639693354f7b,0x00a628dbb6a80c47,0x003a0b0507372953,0x00421113ab45c0d9,0x00e545f08362ab7a,0x0028ce087b4d6d96)},
|
||||
{FIELD_LITERAL(0x00a67ee7cf9f99eb,0x005713b275f2ff68,0x00f1d536a841513d,0x00823b59b024712e,0x009c46b9d0d38cec,0x00cdb1595aa2d7d4,0x008375b3423d9af8,0x000ab0b516d978f7)},
|
||||
{FIELD_LITERAL(0x00428dcb3c510b0f,0x00585607ea24bb4e,0x003736bf1603687a,0x00c47e568c4fe3c7,0x003cd00282848605,0x0043a487c3b91939,0x004ffc04e1095a06,0x00a4c989a3d4b918)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00a8778d0e429f7a,0x004c02b059105a68,0x0016653b609da3ff,0x00d5107bd1a12d27,0x00b4708f9a771cab,0x00bb63b662033f69,0x0072f322240e7215,0x0019445b59c69222)},
|
||||
{FIELD_LITERAL(0x00cf4f6069a658e6,0x0053ca52859436a6,0x0064b994d7e3e117,0x00cb469b9a07f534,0x00cfb68f399e9d47,0x00f0dcb8dac1c6e7,0x00f2ab67f538b3a5,0x0055544f178ab975)},
|
||||
{FIELD_LITERAL(0x0099b7a2685d538c,0x00e2f1897b7c0018,0x003adac8ce48dae3,0x00089276d5c50c0c,0x00172fca07ad6717,0x00cb1a72f54069e5,0x004ee42f133545b3,0x00785f8651362f16)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x0049cbac38509e11,0x0015234505d42cdf,0x00794fb0b5840f1c,0x00496437344045a5,0x0031b6d944e4f9b0,0x00b207318ac1f5d8,0x0000c840da7f5c5d,0x00526f373a5c8814)},
|
||||
{FIELD_LITERAL(0x002c7b7742d1dfd9,0x002cabeb18623c01,0x00055f5e3e044446,0x006c20f3b4ef54ba,0x00c600141ec6b35f,0x00354f437f1a32a3,0x00bac4624a3520f9,0x00c483f734a90691)},
|
||||
{FIELD_LITERAL(0x0053a737d422918d,0x00f7fca1d8758625,0x00c360336dadb04c,0x00f38e3d9158a1b8,0x0069ce3b418e84c6,0x005d1697eca16ead,0x00f8bd6a35ece13d,0x007885dfc2b5afea)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00c3617ae260776c,0x00b20dc3e96922d7,0x00a1a7802246706a,0x00ca6505a5240244,0x002246b62d919782,0x001439102d7aa9b3,0x00e8af1139e6422c,0x00c888d1b52f2b05)},
|
||||
{FIELD_LITERAL(0x005b67690ffd41d9,0x005294f28df516f9,0x00a879272412fcb9,0x00098b629a6d1c8d,0x00fabd3c8050865a,0x00cd7e5b0a3879c5,0x00153238210f3423,0x00357cac101e9f42)},
|
||||
{FIELD_LITERAL(0x008917b454444fb7,0x00f59247c97e441b,0x00a6200a6815152d,0x0009a4228601d254,0x001c0360559bd374,0x007563362039cb36,0x00bd75b48d74e32b,0x0017f515ac3499e8)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x001532a7ffe41c5a,0x00eb1edce358d6bf,0x00ddbacc7b678a7b,0x008a7b70f3c841a3,0x00f1923bf27d3f4c,0x000b2713ed8f7873,0x00aaf67e29047902,0x0044994a70b3976d)},
|
||||
{FIELD_LITERAL(0x00d54e802082d42c,0x00a55aa0dce7cc6c,0x006477b96073f146,0x0082efe4ceb43594,0x00a922bcba026845,0x0077f19d1ab75182,0x00c2bb2737846e59,0x0004d7eec791dd33)},
|
||||
{FIELD_LITERAL(0x0044588d1a81d680,0x00b0a9097208e4f8,0x00212605350dc57e,0x0028717cd2871123,0x00fb083c100fd979,0x0045a056ce063fdf,0x00a5d604b4dd6a41,0x001dabc08ba4e236)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00c4887198d7a7fa,0x00244f98fb45784a,0x0045911e15a15d01,0x001d323d374c0966,0x00967c3915196562,0x0039373abd2f3c67,0x000d2c5614312423,0x0041cf2215442ce3)},
|
||||
{FIELD_LITERAL(0x008ede889ada7f06,0x001611e91de2e135,0x00fdb9a458a471b9,0x00563484e03710d1,0x0031cc81925e3070,0x0062c97b3af80005,0x00fa733eea28edeb,0x00e82457e1ebbc88)},
|
||||
{FIELD_LITERAL(0x006a0df5fe9b6f59,0x00a0d4ff46040d92,0x004a7cedb6f93250,0x00d1df8855b8c357,0x00e73a46086fd058,0x0048fb0add6dfe59,0x001e03a28f1b4e3d,0x00a871c993308d76)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x0030dbb2d1766ec8,0x00586c0ad138555e,0x00d1a34f9e91c77c,0x0063408ad0e89014,0x00d61231b05f6f5b,0x0009abf569f5fd8a,0x00aec67a110f1c43,0x0031d1a790938dd7)},
|
||||
{FIELD_LITERAL(0x006cded841e2a862,0x00198d60af0ab6fb,0x0018f09db809e750,0x004e6ac676016263,0x00eafcd1620969cb,0x002c9784ca34917d,0x0054f00079796de7,0x00d9fab5c5972204)},
|
||||
{FIELD_LITERAL(0x004bd0fee2438a83,0x00b571e62b0f83bd,0x0059287d7ce74800,0x00fb3631b645c3f0,0x00a018e977f78494,0x0091e27065c27b12,0x007696c1817165e0,0x008c40be7c45ba3a)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00a0f326327cb684,0x001c7d0f672680ff,0x008c1c81ffb112d1,0x00f8f801674eddc8,0x00e926d5d48c2a9d,0x005bd6d954c6fe9a,0x004c6b24b4e33703,0x00d05eb5c09105cc)},
|
||||
{FIELD_LITERAL(0x00d61731caacf2cf,0x002df0c7609e01c5,0x00306172208b1e2b,0x00b413fe4fb2b686,0x00826d360902a221,0x003f8d056e67e7f7,0x0065025b0175e989,0x00369add117865eb)},
|
||||
{FIELD_LITERAL(0x00aaf895aec2fa11,0x000f892bc313eb52,0x005b1c794dad050b,0x003f8ec4864cec14,0x00af81058d0b90e5,0x00ebe43e183997bb,0x00a9d610f9f3e615,0x007acd8eec2e88d3)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x0049b2fab13812a3,0x00846db32cd60431,0x000177fa578c8d6c,0x00047d0e2ad4bc51,0x00b158ba38d1e588,0x006a45daad79e3f3,0x000997b93cab887b,0x00c47ea42fa23dc3)},
|
||||
{FIELD_LITERAL(0x0012b6fef7aeb1ca,0x009412768194b6a7,0x00ff0d351f23ab93,0x007e8a14c1aff71b,0x006c1c0170c512bc,0x0016243ea02ab2e5,0x007bb6865b303f3e,0x0015ce6b29b159f4)},
|
||||
{FIELD_LITERAL(0x009961cd02e68108,0x00e2035d3a1d0836,0x005d51f69b5e1a1d,0x004bccb4ea36edcd,0x0069be6a7aeef268,0x0063f4dd9de8d5a7,0x006283783092ca35,0x0075a31af2c35409)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00c412365162e8cf,0x00012283fb34388a,0x003e6543babf39e2,0x00eead6b3a804978,0x0099c0314e8b326f,0x00e98e0a8d477a4f,0x00d2eb96b127a687,0x00ed8d7df87571bb)},
|
||||
{FIELD_LITERAL(0x00777463e308cacf,0x00c8acb93950132d,0x00ebddbf4ca48b2c,0x0026ad7ca0795a0a,0x00f99a3d9a715064,0x000d60bcf9d4dfcc,0x005e65a73a437a06,0x0019d536a8db56c8)},
|
||||
{FIELD_LITERAL(0x00192d7dd558d135,0x0027cd6a8323ffa7,0x00239f1a412dc1e7,0x0046b4b3be74fc5c,0x0020c47a2bef5bce,0x00aa17e48f43862b,0x00f7e26c96342e5f,0x0008011c530f39a9)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x00aad4ac569bf0f1,0x00a67adc90b27740,0x0048551369a5751a,0x0031252584a3306a,0x0084e15df770e6fc,0x00d7bba1c74b5805,0x00a80ef223af1012,0x0089c85ceb843a34)},
|
||||
{FIELD_LITERAL(0x00c4545be4a54004,0x0099e11f60357e6c,0x001f3936d19515a6,0x007793df84341a6e,0x0051061886717ffa,0x00e9b0a660b28f85,0x0044ea685892de0d,0x000257d2a1fda9d9)},
|
||||
{FIELD_LITERAL(0x007e8b01b24ac8a8,0x006cf3b0b5ca1337,0x00f1607d3e36a570,0x0039b7fab82991a1,0x00231777065840c5,0x00998e5afdd346f9,0x00b7dc3e64acc85f,0x00baacc748013ad6)},
|
||||
}}, {{
|
||||
{FIELD_LITERAL(0x008ea6a4177580bf,0x005fa1953e3f0378,0x005fe409ac74d614,0x00452327f477e047,0x00a4018507fb6073,0x007b6e71951caac8,0x0012b42ab8a6ce91,0x0080eca677294ab7)},
|
||||
{FIELD_LITERAL(0x00a53edc023ba69b,0x00c6afa83ddde2e8,0x00c3f638b307b14e,0x004a357a64414062,0x00e4d94d8b582dc9,0x001739caf71695b7,0x0012431b2ae28de1,0x003b6bc98682907c)},
|
||||
{FIELD_LITERAL(0x008a9a93be1f99d6,0x0079fa627cc699c8,0x00b0cfb134ba84c8,0x001c4b778249419a,0x00df4ab3d9c44f40,0x009f596e6c1a9e3c,0x001979c0df237316,0x00501e953a919b87)},
|
||||
}}
|
||||
};
|
||||
const niels_t *curve448_wnaf_base = curve448_wnaf_base_table;
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2015 Cryptography Research, 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 Mike Hamburg
|
||||
*/
|
||||
|
||||
#ifndef HEADER_CURVE448UTILS_H
|
||||
# define HEADER_CURVE448UTILS_H
|
||||
|
||||
# include <openssl/e_os2.h>
|
||||
|
||||
/*
|
||||
* Internal word types. Somewhat tricky. This could be decided separately per
|
||||
* platform. However, the structs do need to be all the same size and
|
||||
* alignment on a given platform to support dynamic linking, since even if you
|
||||
* header was built with eg arch_neon, you might end up linking a library built
|
||||
* with arch_arm32.
|
||||
*/
|
||||
# ifndef C448_WORD_BITS
|
||||
# if (defined(__SIZEOF_INT128__) && (__SIZEOF_INT128__ == 16)) \
|
||||
&& !defined(__sparc__)
|
||||
# define C448_WORD_BITS 64 /* The number of bits in a word */
|
||||
# else
|
||||
# define C448_WORD_BITS 32 /* The number of bits in a word */
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if C448_WORD_BITS == 64
|
||||
/* Word size for internal computations */
|
||||
typedef uint64_t c448_word_t;
|
||||
/* Signed word size for internal computations */
|
||||
typedef int64_t c448_sword_t;
|
||||
/* "Boolean" type, will be set to all-zero or all-one (i.e. -1u) */
|
||||
typedef uint64_t c448_bool_t;
|
||||
/* Double-word size for internal computations */
|
||||
typedef __uint128_t c448_dword_t;
|
||||
/* Signed double-word size for internal computations */
|
||||
typedef __int128_t c448_dsword_t;
|
||||
# elif C448_WORD_BITS == 32
|
||||
/* Word size for internal computations */
|
||||
typedef uint32_t c448_word_t;
|
||||
/* Signed word size for internal computations */
|
||||
typedef int32_t c448_sword_t;
|
||||
/* "Boolean" type, will be set to all-zero or all-one (i.e. -1u) */
|
||||
typedef uint32_t c448_bool_t;
|
||||
/* Double-word size for internal computations */
|
||||
typedef uint64_t c448_dword_t;
|
||||
/* Signed double-word size for internal computations */
|
||||
typedef int64_t c448_dsword_t;
|
||||
# else
|
||||
# error "Only supporting C448_WORD_BITS = 32 or 64 for now"
|
||||
# endif
|
||||
|
||||
/* C448_TRUE = -1 so that C448_TRUE & x = x */
|
||||
# define C448_TRUE (0 - (c448_bool_t)1)
|
||||
|
||||
/* C448_FALSE = 0 so that C448_FALSE & x = 0 */
|
||||
# define C448_FALSE 0
|
||||
|
||||
/* Another boolean type used to indicate success or failure. */
|
||||
typedef enum {
|
||||
C448_SUCCESS = -1, /**< The operation succeeded. */
|
||||
C448_FAILURE = 0 /**< The operation failed. */
|
||||
} c448_error_t;
|
||||
|
||||
/* Return success if x is true */
|
||||
static ossl_inline c448_error_t c448_succeed_if(c448_bool_t x)
|
||||
{
|
||||
return (c448_error_t) x;
|
||||
}
|
||||
|
||||
#endif /* __C448_COMMON_H__ */
|
||||
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
* Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2015-2016 Cryptography Research, 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 Mike Hamburg
|
||||
*/
|
||||
|
||||
#ifndef HEADER_ED448_H
|
||||
# define HEADER_ED448_H
|
||||
|
||||
# include "point_448.h"
|
||||
|
||||
/* Number of bytes in an EdDSA public key. */
|
||||
# define EDDSA_448_PUBLIC_BYTES 57
|
||||
|
||||
/* Number of bytes in an EdDSA private key. */
|
||||
# define EDDSA_448_PRIVATE_BYTES EDDSA_448_PUBLIC_BYTES
|
||||
|
||||
/* Number of bytes in an EdDSA private key. */
|
||||
# define EDDSA_448_SIGNATURE_BYTES (EDDSA_448_PUBLIC_BYTES + \
|
||||
EDDSA_448_PRIVATE_BYTES)
|
||||
|
||||
/* EdDSA encoding ratio. */
|
||||
# define C448_EDDSA_ENCODE_RATIO 4
|
||||
|
||||
/* EdDSA decoding ratio. */
|
||||
# define C448_EDDSA_DECODE_RATIO (4 / 4)
|
||||
|
||||
/*
|
||||
* EdDSA key generation. This function uses a different (non-Decaf) encoding.
|
||||
*
|
||||
* pubkey (out): The public key.
|
||||
* privkey (in): The private key.
|
||||
*/
|
||||
c448_error_t c448_ed448_derive_public_key(
|
||||
uint8_t pubkey [EDDSA_448_PUBLIC_BYTES],
|
||||
const uint8_t privkey [EDDSA_448_PRIVATE_BYTES]);
|
||||
|
||||
/*
|
||||
* EdDSA signing.
|
||||
*
|
||||
* signature (out): The signature.
|
||||
* privkey (in): The private key.
|
||||
* pubkey (in): The public key.
|
||||
* message (in): The message to sign.
|
||||
* message_len (in): The length of the message.
|
||||
* prehashed (in): Nonzero if the message is actually the hash of something
|
||||
* you want to sign.
|
||||
* context (in): A "context" for this signature of up to 255 bytes.
|
||||
* context_len (in): Length of the context.
|
||||
*
|
||||
* For Ed25519, it is unsafe to use the same key for both prehashed and
|
||||
* non-prehashed messages, at least without some very careful protocol-level
|
||||
* disambiguation. For Ed448 it is safe.
|
||||
*/
|
||||
c448_error_t c448_ed448_sign(
|
||||
uint8_t signature[EDDSA_448_SIGNATURE_BYTES],
|
||||
const uint8_t privkey[EDDSA_448_PRIVATE_BYTES],
|
||||
const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES],
|
||||
const uint8_t *message, size_t message_len,
|
||||
uint8_t prehashed, const uint8_t *context,
|
||||
size_t context_len);
|
||||
|
||||
/*
|
||||
* EdDSA signing with prehash.
|
||||
*
|
||||
* signature (out): The signature.
|
||||
* privkey (in): The private key.
|
||||
* pubkey (in): The public key.
|
||||
* hash (in): The hash of the message. This object will not be modified by the
|
||||
* call.
|
||||
* context (in): A "context" for this signature of up to 255 bytes. Must be the
|
||||
* same as what was used for the prehash.
|
||||
* context_len (in): Length of the context.
|
||||
*
|
||||
* For Ed25519, it is unsafe to use the same key for both prehashed and
|
||||
* non-prehashed messages, at least without some very careful protocol-level
|
||||
* disambiguation. For Ed448 it is safe.
|
||||
*/
|
||||
c448_error_t c448_ed448_sign_prehash(
|
||||
uint8_t signature[EDDSA_448_SIGNATURE_BYTES],
|
||||
const uint8_t privkey[EDDSA_448_PRIVATE_BYTES],
|
||||
const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES],
|
||||
const uint8_t hash[64],
|
||||
const uint8_t *context,
|
||||
size_t context_len);
|
||||
|
||||
/*
|
||||
* EdDSA signature verification.
|
||||
*
|
||||
* Uses the standard (i.e. less-strict) verification formula.
|
||||
*
|
||||
* signature (in): The signature.
|
||||
* pubkey (in): The public key.
|
||||
* message (in): The message to verify.
|
||||
* message_len (in): The length of the message.
|
||||
* prehashed (in): Nonzero if the message is actually the hash of something you
|
||||
* want to verify.
|
||||
* context (in): A "context" for this signature of up to 255 bytes.
|
||||
* context_len (in): Length of the context.
|
||||
*
|
||||
* For Ed25519, it is unsafe to use the same key for both prehashed and
|
||||
* non-prehashed messages, at least without some very careful protocol-level
|
||||
* disambiguation. For Ed448 it is safe.
|
||||
*/
|
||||
c448_error_t c448_ed448_verify(const uint8_t
|
||||
signature[EDDSA_448_SIGNATURE_BYTES],
|
||||
const uint8_t
|
||||
pubkey[EDDSA_448_PUBLIC_BYTES],
|
||||
const uint8_t *message, size_t message_len,
|
||||
uint8_t prehashed, const uint8_t *context,
|
||||
uint8_t context_len);
|
||||
|
||||
/*
|
||||
* EdDSA signature verification.
|
||||
*
|
||||
* Uses the standard (i.e. less-strict) verification formula.
|
||||
*
|
||||
* signature (in): The signature.
|
||||
* pubkey (in): The public key.
|
||||
* hash (in): The hash of the message. This object will not be modified by the
|
||||
* call.
|
||||
* context (in): A "context" for this signature of up to 255 bytes. Must be the
|
||||
* same as what was used for the prehash.
|
||||
* context_len (in): Length of the context.
|
||||
*
|
||||
* For Ed25519, it is unsafe to use the same key for both prehashed and
|
||||
* non-prehashed messages, at least without some very careful protocol-level
|
||||
* disambiguation. For Ed448 it is safe.
|
||||
*/
|
||||
c448_error_t c448_ed448_verify_prehash(
|
||||
const uint8_t signature[EDDSA_448_SIGNATURE_BYTES],
|
||||
const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES],
|
||||
const uint8_t hash[64],
|
||||
const uint8_t *context,
|
||||
uint8_t context_len);
|
||||
|
||||
/*
|
||||
* EdDSA point encoding. Used internally, exposed externally.
|
||||
* Multiplies by C448_EDDSA_ENCODE_RATIO first.
|
||||
*
|
||||
* The multiplication is required because the EdDSA encoding represents
|
||||
* the cofactor information, but the Decaf encoding ignores it (which
|
||||
* is the whole point). So if you decode from EdDSA and re-encode to
|
||||
* EdDSA, the cofactor info must get cleared, because the intermediate
|
||||
* representation doesn't track it.
|
||||
*
|
||||
* The way we handle this is to multiply by C448_EDDSA_DECODE_RATIO when
|
||||
* decoding, and by C448_EDDSA_ENCODE_RATIO when encoding. The product of
|
||||
* these ratios is always exactly the cofactor 4, so the cofactor ends up
|
||||
* cleared one way or another. But exactly how that shakes out depends on the
|
||||
* base points specified in RFC 8032.
|
||||
*
|
||||
* The upshot is that if you pass the Decaf/Ristretto base point to
|
||||
* this function, you will get C448_EDDSA_ENCODE_RATIO times the
|
||||
* EdDSA base point.
|
||||
*
|
||||
* enc (out): The encoded point.
|
||||
* p (in): The point.
|
||||
*/
|
||||
void curve448_point_mul_by_ratio_and_encode_like_eddsa(
|
||||
uint8_t enc [EDDSA_448_PUBLIC_BYTES],
|
||||
const curve448_point_t p);
|
||||
|
||||
/*
|
||||
* EdDSA point decoding. Multiplies by C448_EDDSA_DECODE_RATIO, and
|
||||
* ignores cofactor information.
|
||||
*
|
||||
* See notes on curve448_point_mul_by_ratio_and_encode_like_eddsa
|
||||
*
|
||||
* enc (out): The encoded point.
|
||||
* p (in): The point.
|
||||
*/
|
||||
c448_error_t curve448_point_decode_like_eddsa_and_mul_by_ratio(
|
||||
curve448_point_t p,
|
||||
const uint8_t enc[EDDSA_448_PUBLIC_BYTES]);
|
||||
|
||||
/*
|
||||
* EdDSA to ECDH private key conversion
|
||||
* Using the appropriate hash function, hash the EdDSA private key
|
||||
* and keep only the lower bytes to get the ECDH private key
|
||||
*
|
||||
* x (out): The ECDH private key as in RFC7748
|
||||
* ed (in): The EdDSA private key
|
||||
*/
|
||||
c448_error_t c448_ed448_convert_private_key_to_x448(
|
||||
uint8_t x[X448_PRIVATE_BYTES],
|
||||
const uint8_t ed[EDDSA_448_PRIVATE_BYTES]);
|
||||
|
||||
#endif /* HEADER_ED448_H */
|
||||
@@ -0,0 +1,353 @@
|
||||
/*
|
||||
* Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2015-2016 Cryptography Research, 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 Mike Hamburg
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/evp.h>
|
||||
#include "curve448_lcl.h"
|
||||
#include "word.h"
|
||||
#include "ed448.h"
|
||||
#include "internal/numbers.h"
|
||||
|
||||
#define COFACTOR 4
|
||||
|
||||
static c448_error_t oneshot_hash(uint8_t *out, size_t outlen,
|
||||
const uint8_t *in, size_t inlen)
|
||||
{
|
||||
EVP_MD_CTX *hashctx = EVP_MD_CTX_new();
|
||||
|
||||
if (hashctx == NULL)
|
||||
return C448_FAILURE;
|
||||
|
||||
if (!EVP_DigestInit_ex(hashctx, EVP_shake256(), NULL)
|
||||
|| !EVP_DigestUpdate(hashctx, in, inlen)
|
||||
|| !EVP_DigestFinalXOF(hashctx, out, outlen)) {
|
||||
EVP_MD_CTX_free(hashctx);
|
||||
return C448_FAILURE;
|
||||
}
|
||||
|
||||
EVP_MD_CTX_free(hashctx);
|
||||
return C448_SUCCESS;
|
||||
}
|
||||
|
||||
static void clamp(uint8_t secret_scalar_ser[EDDSA_448_PRIVATE_BYTES])
|
||||
{
|
||||
secret_scalar_ser[0] &= -COFACTOR;
|
||||
secret_scalar_ser[EDDSA_448_PRIVATE_BYTES - 1] = 0;
|
||||
secret_scalar_ser[EDDSA_448_PRIVATE_BYTES - 2] |= 0x80;
|
||||
}
|
||||
|
||||
static c448_error_t hash_init_with_dom(EVP_MD_CTX *hashctx, uint8_t prehashed,
|
||||
uint8_t for_prehash,
|
||||
const uint8_t *context,
|
||||
size_t context_len)
|
||||
{
|
||||
const char *dom_s = "SigEd448";
|
||||
uint8_t dom[2];
|
||||
|
||||
if (context_len > UINT8_MAX)
|
||||
return C448_FAILURE;
|
||||
|
||||
dom[0] = (uint8_t)(2 - (prehashed == 0 ? 1 : 0)
|
||||
- (for_prehash == 0 ? 1 : 0));
|
||||
dom[1] = (uint8_t)context_len;
|
||||
|
||||
if (!EVP_DigestInit_ex(hashctx, EVP_shake256(), NULL)
|
||||
|| !EVP_DigestUpdate(hashctx, dom_s, strlen(dom_s))
|
||||
|| !EVP_DigestUpdate(hashctx, dom, sizeof(dom))
|
||||
|| (context_len > 0
|
||||
&& !EVP_DigestUpdate(hashctx, context, context_len)))
|
||||
return C448_FAILURE;
|
||||
|
||||
return C448_SUCCESS;
|
||||
}
|
||||
|
||||
/* In this file because it uses the hash */
|
||||
c448_error_t c448_ed448_convert_private_key_to_x448(
|
||||
uint8_t x[X448_PRIVATE_BYTES],
|
||||
const uint8_t ed [EDDSA_448_PRIVATE_BYTES])
|
||||
{
|
||||
/* pass the private key through oneshot_hash function */
|
||||
/* and keep the first X448_PRIVATE_BYTES bytes */
|
||||
return oneshot_hash(x, X448_PRIVATE_BYTES, ed,
|
||||
EDDSA_448_PRIVATE_BYTES);
|
||||
}
|
||||
|
||||
c448_error_t c448_ed448_derive_public_key(
|
||||
uint8_t pubkey[EDDSA_448_PUBLIC_BYTES],
|
||||
const uint8_t privkey[EDDSA_448_PRIVATE_BYTES])
|
||||
{
|
||||
/* only this much used for keygen */
|
||||
uint8_t secret_scalar_ser[EDDSA_448_PRIVATE_BYTES];
|
||||
curve448_scalar_t secret_scalar;
|
||||
unsigned int c;
|
||||
curve448_point_t p;
|
||||
|
||||
if (!oneshot_hash(secret_scalar_ser, sizeof(secret_scalar_ser), privkey,
|
||||
EDDSA_448_PRIVATE_BYTES))
|
||||
return C448_FAILURE;
|
||||
|
||||
clamp(secret_scalar_ser);
|
||||
|
||||
curve448_scalar_decode_long(secret_scalar, secret_scalar_ser,
|
||||
sizeof(secret_scalar_ser));
|
||||
|
||||
/*
|
||||
* Since we are going to mul_by_cofactor during encoding, divide by it
|
||||
* here. However, the EdDSA base point is not the same as the decaf base
|
||||
* point if the sigma isogeny is in use: the EdDSA base point is on
|
||||
* Etwist_d/(1-d) and the decaf base point is on Etwist_d, and when
|
||||
* converted it effectively picks up a factor of 2 from the isogenies. So
|
||||
* we might start at 2 instead of 1.
|
||||
*/
|
||||
for (c = 1; c < C448_EDDSA_ENCODE_RATIO; c <<= 1)
|
||||
curve448_scalar_halve(secret_scalar, secret_scalar);
|
||||
|
||||
curve448_precomputed_scalarmul(p, curve448_precomputed_base, secret_scalar);
|
||||
|
||||
curve448_point_mul_by_ratio_and_encode_like_eddsa(pubkey, p);
|
||||
|
||||
/* Cleanup */
|
||||
curve448_scalar_destroy(secret_scalar);
|
||||
curve448_point_destroy(p);
|
||||
OPENSSL_cleanse(secret_scalar_ser, sizeof(secret_scalar_ser));
|
||||
|
||||
return C448_SUCCESS;
|
||||
}
|
||||
|
||||
c448_error_t c448_ed448_sign(
|
||||
uint8_t signature[EDDSA_448_SIGNATURE_BYTES],
|
||||
const uint8_t privkey[EDDSA_448_PRIVATE_BYTES],
|
||||
const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES],
|
||||
const uint8_t *message, size_t message_len,
|
||||
uint8_t prehashed, const uint8_t *context,
|
||||
size_t context_len)
|
||||
{
|
||||
curve448_scalar_t secret_scalar;
|
||||
EVP_MD_CTX *hashctx = EVP_MD_CTX_new();
|
||||
c448_error_t ret = C448_FAILURE;
|
||||
curve448_scalar_t nonce_scalar;
|
||||
uint8_t nonce_point[EDDSA_448_PUBLIC_BYTES] = { 0 };
|
||||
unsigned int c;
|
||||
curve448_scalar_t challenge_scalar;
|
||||
|
||||
if (hashctx == NULL)
|
||||
return C448_FAILURE;
|
||||
|
||||
{
|
||||
/*
|
||||
* Schedule the secret key, First EDDSA_448_PRIVATE_BYTES is serialised
|
||||
* secret scalar,next EDDSA_448_PRIVATE_BYTES bytes is the seed.
|
||||
*/
|
||||
uint8_t expanded[EDDSA_448_PRIVATE_BYTES * 2];
|
||||
|
||||
if (!oneshot_hash(expanded, sizeof(expanded), privkey,
|
||||
EDDSA_448_PRIVATE_BYTES))
|
||||
goto err;
|
||||
clamp(expanded);
|
||||
curve448_scalar_decode_long(secret_scalar, expanded,
|
||||
EDDSA_448_PRIVATE_BYTES);
|
||||
|
||||
/* Hash to create the nonce */
|
||||
if (!hash_init_with_dom(hashctx, prehashed, 0, context, context_len)
|
||||
|| !EVP_DigestUpdate(hashctx,
|
||||
expanded + EDDSA_448_PRIVATE_BYTES,
|
||||
EDDSA_448_PRIVATE_BYTES)
|
||||
|| (message_len > 0
|
||||
&& !EVP_DigestUpdate(hashctx, message, message_len))) {
|
||||
OPENSSL_cleanse(expanded, sizeof(expanded));
|
||||
goto err;
|
||||
}
|
||||
OPENSSL_cleanse(expanded, sizeof(expanded));
|
||||
}
|
||||
|
||||
/* Decode the nonce */
|
||||
{
|
||||
uint8_t nonce[2 * EDDSA_448_PRIVATE_BYTES];
|
||||
|
||||
if (!EVP_DigestFinalXOF(hashctx, nonce, sizeof(nonce)))
|
||||
goto err;
|
||||
curve448_scalar_decode_long(nonce_scalar, nonce, sizeof(nonce));
|
||||
OPENSSL_cleanse(nonce, sizeof(nonce));
|
||||
}
|
||||
|
||||
{
|
||||
/* Scalarmul to create the nonce-point */
|
||||
curve448_scalar_t nonce_scalar_2;
|
||||
curve448_point_t p;
|
||||
|
||||
curve448_scalar_halve(nonce_scalar_2, nonce_scalar);
|
||||
for (c = 2; c < C448_EDDSA_ENCODE_RATIO; c <<= 1)
|
||||
curve448_scalar_halve(nonce_scalar_2, nonce_scalar_2);
|
||||
|
||||
curve448_precomputed_scalarmul(p, curve448_precomputed_base,
|
||||
nonce_scalar_2);
|
||||
curve448_point_mul_by_ratio_and_encode_like_eddsa(nonce_point, p);
|
||||
curve448_point_destroy(p);
|
||||
curve448_scalar_destroy(nonce_scalar_2);
|
||||
}
|
||||
|
||||
{
|
||||
uint8_t challenge[2 * EDDSA_448_PRIVATE_BYTES];
|
||||
|
||||
/* Compute the challenge */
|
||||
if (!hash_init_with_dom(hashctx, prehashed, 0, context, context_len)
|
||||
|| !EVP_DigestUpdate(hashctx, nonce_point, sizeof(nonce_point))
|
||||
|| !EVP_DigestUpdate(hashctx, pubkey, EDDSA_448_PUBLIC_BYTES)
|
||||
|| (message_len > 0
|
||||
&& !EVP_DigestUpdate(hashctx, message, message_len))
|
||||
|| !EVP_DigestFinalXOF(hashctx, challenge, sizeof(challenge)))
|
||||
goto err;
|
||||
|
||||
curve448_scalar_decode_long(challenge_scalar, challenge,
|
||||
sizeof(challenge));
|
||||
OPENSSL_cleanse(challenge, sizeof(challenge));
|
||||
}
|
||||
|
||||
curve448_scalar_mul(challenge_scalar, challenge_scalar, secret_scalar);
|
||||
curve448_scalar_add(challenge_scalar, challenge_scalar, nonce_scalar);
|
||||
|
||||
OPENSSL_cleanse(signature, EDDSA_448_SIGNATURE_BYTES);
|
||||
memcpy(signature, nonce_point, sizeof(nonce_point));
|
||||
curve448_scalar_encode(&signature[EDDSA_448_PUBLIC_BYTES],
|
||||
challenge_scalar);
|
||||
|
||||
curve448_scalar_destroy(secret_scalar);
|
||||
curve448_scalar_destroy(nonce_scalar);
|
||||
curve448_scalar_destroy(challenge_scalar);
|
||||
|
||||
ret = C448_SUCCESS;
|
||||
err:
|
||||
EVP_MD_CTX_free(hashctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
c448_error_t c448_ed448_sign_prehash(
|
||||
uint8_t signature[EDDSA_448_SIGNATURE_BYTES],
|
||||
const uint8_t privkey[EDDSA_448_PRIVATE_BYTES],
|
||||
const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES],
|
||||
const uint8_t hash[64], const uint8_t *context,
|
||||
size_t context_len)
|
||||
{
|
||||
return c448_ed448_sign(signature, privkey, pubkey, hash, 64, 1, context,
|
||||
context_len);
|
||||
}
|
||||
|
||||
c448_error_t c448_ed448_verify(
|
||||
const uint8_t signature[EDDSA_448_SIGNATURE_BYTES],
|
||||
const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES],
|
||||
const uint8_t *message, size_t message_len,
|
||||
uint8_t prehashed, const uint8_t *context,
|
||||
uint8_t context_len)
|
||||
{
|
||||
curve448_point_t pk_point, r_point;
|
||||
c448_error_t error =
|
||||
curve448_point_decode_like_eddsa_and_mul_by_ratio(pk_point, pubkey);
|
||||
curve448_scalar_t challenge_scalar;
|
||||
curve448_scalar_t response_scalar;
|
||||
unsigned int c;
|
||||
|
||||
if (C448_SUCCESS != error)
|
||||
return error;
|
||||
|
||||
error =
|
||||
curve448_point_decode_like_eddsa_and_mul_by_ratio(r_point, signature);
|
||||
if (C448_SUCCESS != error)
|
||||
return error;
|
||||
|
||||
{
|
||||
/* Compute the challenge */
|
||||
EVP_MD_CTX *hashctx = EVP_MD_CTX_new();
|
||||
uint8_t challenge[2 * EDDSA_448_PRIVATE_BYTES];
|
||||
|
||||
if (hashctx == NULL
|
||||
|| !hash_init_with_dom(hashctx, prehashed, 0, context,
|
||||
context_len)
|
||||
|| !EVP_DigestUpdate(hashctx, signature, EDDSA_448_PUBLIC_BYTES)
|
||||
|| !EVP_DigestUpdate(hashctx, pubkey, EDDSA_448_PUBLIC_BYTES)
|
||||
|| !EVP_DigestUpdate(hashctx, message, message_len)
|
||||
|| !EVP_DigestFinalXOF(hashctx, challenge, sizeof(challenge))) {
|
||||
EVP_MD_CTX_free(hashctx);
|
||||
return C448_FAILURE;
|
||||
}
|
||||
|
||||
EVP_MD_CTX_free(hashctx);
|
||||
curve448_scalar_decode_long(challenge_scalar, challenge,
|
||||
sizeof(challenge));
|
||||
OPENSSL_cleanse(challenge, sizeof(challenge));
|
||||
}
|
||||
curve448_scalar_sub(challenge_scalar, curve448_scalar_zero,
|
||||
challenge_scalar);
|
||||
|
||||
curve448_scalar_decode_long(response_scalar,
|
||||
&signature[EDDSA_448_PUBLIC_BYTES],
|
||||
EDDSA_448_PRIVATE_BYTES);
|
||||
|
||||
for (c = 1; c < C448_EDDSA_DECODE_RATIO; c <<= 1)
|
||||
curve448_scalar_add(response_scalar, response_scalar, response_scalar);
|
||||
|
||||
/* pk_point = -c(x(P)) + (cx + k)G = kG */
|
||||
curve448_base_double_scalarmul_non_secret(pk_point,
|
||||
response_scalar,
|
||||
pk_point, challenge_scalar);
|
||||
return c448_succeed_if(curve448_point_eq(pk_point, r_point));
|
||||
}
|
||||
|
||||
c448_error_t c448_ed448_verify_prehash(
|
||||
const uint8_t signature[EDDSA_448_SIGNATURE_BYTES],
|
||||
const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES],
|
||||
const uint8_t hash[64], const uint8_t *context,
|
||||
uint8_t context_len)
|
||||
{
|
||||
return c448_ed448_verify(signature, pubkey, hash, 64, 1, context,
|
||||
context_len);
|
||||
}
|
||||
|
||||
int ED448_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len,
|
||||
const uint8_t public_key[57], const uint8_t private_key[57],
|
||||
const uint8_t *context, size_t context_len)
|
||||
{
|
||||
return c448_ed448_sign(out_sig, private_key, public_key, message,
|
||||
message_len, 0, context, context_len)
|
||||
== C448_SUCCESS;
|
||||
}
|
||||
|
||||
int ED448_verify(const uint8_t *message, size_t message_len,
|
||||
const uint8_t signature[114], const uint8_t public_key[57],
|
||||
const uint8_t *context, size_t context_len)
|
||||
{
|
||||
return c448_ed448_verify(signature, public_key, message, message_len, 0,
|
||||
context, (uint8_t)context_len) == C448_SUCCESS;
|
||||
}
|
||||
|
||||
int ED448ph_sign(uint8_t *out_sig, const uint8_t hash[64],
|
||||
const uint8_t public_key[57], const uint8_t private_key[57],
|
||||
const uint8_t *context, size_t context_len)
|
||||
{
|
||||
return c448_ed448_sign_prehash(out_sig, private_key, public_key, hash,
|
||||
context, context_len) == C448_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
int ED448ph_verify(const uint8_t hash[64], const uint8_t signature[114],
|
||||
const uint8_t public_key[57], const uint8_t *context,
|
||||
size_t context_len)
|
||||
{
|
||||
return c448_ed448_verify_prehash(signature, public_key, hash, context,
|
||||
(uint8_t)context_len) == C448_SUCCESS;
|
||||
}
|
||||
|
||||
int ED448_public_from_private(uint8_t out_public_key[57],
|
||||
const uint8_t private_key[57])
|
||||
{
|
||||
return c448_ed448_derive_public_key(out_public_key, private_key)
|
||||
== C448_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2015-2016 Cryptography Research, 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 Mike Hamburg
|
||||
*/
|
||||
#include "field.h"
|
||||
|
||||
static const gf MODULUS = {
|
||||
FIELD_LITERAL(0xffffffffffffff, 0xffffffffffffff, 0xffffffffffffff,
|
||||
0xffffffffffffff, 0xfffffffffffffe, 0xffffffffffffff,
|
||||
0xffffffffffffff, 0xffffffffffffff)
|
||||
};
|
||||
|
||||
/* Serialize to wire format. */
|
||||
void gf_serialize(uint8_t serial[SER_BYTES], const gf x, int with_hibit)
|
||||
{
|
||||
unsigned int j = 0, fill = 0;
|
||||
dword_t buffer = 0;
|
||||
int i;
|
||||
gf red;
|
||||
|
||||
gf_copy(red, x);
|
||||
gf_strong_reduce(red);
|
||||
if (!with_hibit)
|
||||
assert(gf_hibit(red) == 0);
|
||||
|
||||
for (i = 0; i < (with_hibit ? X_SER_BYTES : SER_BYTES); i++) {
|
||||
if (fill < 8 && j < NLIMBS) {
|
||||
buffer |= ((dword_t) red->limb[LIMBPERM(j)]) << fill;
|
||||
fill += LIMB_PLACE_VALUE(LIMBPERM(j));
|
||||
j++;
|
||||
}
|
||||
serial[i] = (uint8_t)buffer;
|
||||
fill -= 8;
|
||||
buffer >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return high bit of x = low bit of 2x mod p */
|
||||
mask_t gf_hibit(const gf x)
|
||||
{
|
||||
gf y;
|
||||
|
||||
gf_add(y, x, x);
|
||||
gf_strong_reduce(y);
|
||||
return 0 - (y->limb[0] & 1);
|
||||
}
|
||||
|
||||
/* Return high bit of x = low bit of 2x mod p */
|
||||
mask_t gf_lobit(const gf x)
|
||||
{
|
||||
gf y;
|
||||
|
||||
gf_copy(y, x);
|
||||
gf_strong_reduce(y);
|
||||
return 0 - (y->limb[0] & 1);
|
||||
}
|
||||
|
||||
/* Deserialize from wire format; return -1 on success and 0 on failure. */
|
||||
mask_t gf_deserialize(gf x, const uint8_t serial[SER_BYTES], int with_hibit,
|
||||
uint8_t hi_nmask)
|
||||
{
|
||||
unsigned int j = 0, fill = 0;
|
||||
dword_t buffer = 0;
|
||||
dsword_t scarry = 0;
|
||||
const unsigned nbytes = with_hibit ? X_SER_BYTES : SER_BYTES;
|
||||
unsigned int i;
|
||||
mask_t succ;
|
||||
|
||||
for (i = 0; i < NLIMBS; i++) {
|
||||
while (fill < LIMB_PLACE_VALUE(LIMBPERM(i)) && j < nbytes) {
|
||||
uint8_t sj;
|
||||
|
||||
sj = serial[j];
|
||||
if (j == nbytes - 1)
|
||||
sj &= ~hi_nmask;
|
||||
buffer |= ((dword_t) sj) << fill;
|
||||
fill += 8;
|
||||
j++;
|
||||
}
|
||||
x->limb[LIMBPERM(i)] = (word_t)
|
||||
((i < NLIMBS - 1) ? buffer & LIMB_MASK(LIMBPERM(i)) : buffer);
|
||||
fill -= LIMB_PLACE_VALUE(LIMBPERM(i));
|
||||
buffer >>= LIMB_PLACE_VALUE(LIMBPERM(i));
|
||||
scarry =
|
||||
(scarry + x->limb[LIMBPERM(i)] -
|
||||
MODULUS->limb[LIMBPERM(i)]) >> (8 * sizeof(word_t));
|
||||
}
|
||||
succ = with_hibit ? 0 - (mask_t) 1 : ~gf_hibit(x);
|
||||
return succ & word_is_zero((word_t)buffer) & ~word_is_zero((word_t)scarry);
|
||||
}
|
||||
|
||||
/* Reduce to canonical form. */
|
||||
void gf_strong_reduce(gf a)
|
||||
{
|
||||
dsword_t scarry;
|
||||
word_t scarry_0;
|
||||
dword_t carry = 0;
|
||||
unsigned int i;
|
||||
|
||||
/* first, clear high */
|
||||
gf_weak_reduce(a); /* Determined to have negligible perf impact. */
|
||||
|
||||
/* now the total is less than 2p */
|
||||
|
||||
/* compute total_value - p. No need to reduce mod p. */
|
||||
scarry = 0;
|
||||
for (i = 0; i < NLIMBS; i++) {
|
||||
scarry = scarry + a->limb[LIMBPERM(i)] - MODULUS->limb[LIMBPERM(i)];
|
||||
a->limb[LIMBPERM(i)] = scarry & LIMB_MASK(LIMBPERM(i));
|
||||
scarry >>= LIMB_PLACE_VALUE(LIMBPERM(i));
|
||||
}
|
||||
|
||||
/*
|
||||
* uncommon case: it was >= p, so now scarry = 0 and this = x common case:
|
||||
* it was < p, so now scarry = -1 and this = x - p + 2^255 so let's add
|
||||
* back in p. will carry back off the top for 2^255.
|
||||
*/
|
||||
assert(word_is_zero(scarry) | word_is_zero(scarry + 1));
|
||||
|
||||
scarry_0 = (word_t)scarry;
|
||||
|
||||
/* add it back */
|
||||
for (i = 0; i < NLIMBS; i++) {
|
||||
carry =
|
||||
carry + a->limb[LIMBPERM(i)] +
|
||||
(scarry_0 & MODULUS->limb[LIMBPERM(i)]);
|
||||
a->limb[LIMBPERM(i)] = carry & LIMB_MASK(LIMBPERM(i));
|
||||
carry >>= LIMB_PLACE_VALUE(LIMBPERM(i));
|
||||
}
|
||||
|
||||
assert(word_is_zero(carry + scarry_0));
|
||||
}
|
||||
|
||||
/* Subtract two gf elements d=a-b */
|
||||
void gf_sub(gf d, const gf a, const gf b)
|
||||
{
|
||||
gf_sub_RAW(d, a, b);
|
||||
gf_bias(d, 2);
|
||||
gf_weak_reduce(d);
|
||||
}
|
||||
|
||||
/* Add two field elements d = a+b */
|
||||
void gf_add(gf d, const gf a, const gf b)
|
||||
{
|
||||
gf_add_RAW(d, a, b);
|
||||
gf_weak_reduce(d);
|
||||
}
|
||||
|
||||
/* Compare a==b */
|
||||
mask_t gf_eq(const gf a, const gf b)
|
||||
{
|
||||
gf c;
|
||||
mask_t ret = 0;
|
||||
unsigned int i;
|
||||
|
||||
gf_sub(c, a, b);
|
||||
gf_strong_reduce(c);
|
||||
|
||||
for (i = 0; i < NLIMBS; i++)
|
||||
ret |= c->limb[LIMBPERM(i)];
|
||||
|
||||
return word_is_zero(ret);
|
||||
}
|
||||
|
||||
mask_t gf_isr(gf a, const gf x)
|
||||
{
|
||||
gf L0, L1, L2;
|
||||
|
||||
gf_sqr(L1, x);
|
||||
gf_mul(L2, x, L1);
|
||||
gf_sqr(L1, L2);
|
||||
gf_mul(L2, x, L1);
|
||||
gf_sqrn(L1, L2, 3);
|
||||
gf_mul(L0, L2, L1);
|
||||
gf_sqrn(L1, L0, 3);
|
||||
gf_mul(L0, L2, L1);
|
||||
gf_sqrn(L2, L0, 9);
|
||||
gf_mul(L1, L0, L2);
|
||||
gf_sqr(L0, L1);
|
||||
gf_mul(L2, x, L0);
|
||||
gf_sqrn(L0, L2, 18);
|
||||
gf_mul(L2, L1, L0);
|
||||
gf_sqrn(L0, L2, 37);
|
||||
gf_mul(L1, L2, L0);
|
||||
gf_sqrn(L0, L1, 37);
|
||||
gf_mul(L1, L2, L0);
|
||||
gf_sqrn(L0, L1, 111);
|
||||
gf_mul(L2, L1, L0);
|
||||
gf_sqr(L0, L2);
|
||||
gf_mul(L1, x, L0);
|
||||
gf_sqrn(L0, L1, 223);
|
||||
gf_mul(L1, L2, L0);
|
||||
gf_sqr(L2, L1);
|
||||
gf_mul(L0, L2, x);
|
||||
gf_copy(a, L1);
|
||||
return gf_eq(L0, ONE);
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2014 Cryptography Research, 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 Mike Hamburg
|
||||
*/
|
||||
|
||||
#ifndef HEADER_FIELD_H
|
||||
# define HEADER_FIELD_H
|
||||
|
||||
# include "internal/constant_time_locl.h"
|
||||
# include <string.h>
|
||||
# include <assert.h>
|
||||
# include "word.h"
|
||||
|
||||
# define NLIMBS (64/sizeof(word_t))
|
||||
# define X_SER_BYTES 56
|
||||
# define SER_BYTES 56
|
||||
|
||||
# if defined(__GNUC__) || defined(__clang__)
|
||||
# define INLINE_UNUSED __inline__ __attribute__((__unused__,__always_inline__))
|
||||
# define RESTRICT __restrict__
|
||||
# define ALIGNED __attribute__((__aligned__(32)))
|
||||
# else
|
||||
# define INLINE_UNUSED ossl_inline
|
||||
# define RESTRICT
|
||||
# define ALIGNED
|
||||
# endif
|
||||
|
||||
typedef struct gf_s {
|
||||
word_t limb[NLIMBS];
|
||||
} ALIGNED gf_s, gf[1];
|
||||
|
||||
/* RFC 7748 support */
|
||||
# define X_PUBLIC_BYTES X_SER_BYTES
|
||||
# define X_PRIVATE_BYTES X_PUBLIC_BYTES
|
||||
# define X_PRIVATE_BITS 448
|
||||
|
||||
static INLINE_UNUSED void gf_copy(gf out, const gf a)
|
||||
{
|
||||
*out = *a;
|
||||
}
|
||||
|
||||
static INLINE_UNUSED void gf_add_RAW(gf out, const gf a, const gf b);
|
||||
static INLINE_UNUSED void gf_sub_RAW(gf out, const gf a, const gf b);
|
||||
static INLINE_UNUSED void gf_bias(gf inout, int amount);
|
||||
static INLINE_UNUSED void gf_weak_reduce(gf inout);
|
||||
|
||||
void gf_strong_reduce(gf inout);
|
||||
void gf_add(gf out, const gf a, const gf b);
|
||||
void gf_sub(gf out, const gf a, const gf b);
|
||||
void gf_mul(gf_s * RESTRICT out, const gf a, const gf b);
|
||||
void gf_mulw_unsigned(gf_s * RESTRICT out, const gf a, uint32_t b);
|
||||
void gf_sqr(gf_s * RESTRICT out, const gf a);
|
||||
mask_t gf_isr(gf a, const gf x); /** a^2 x = 1, QNR, or 0 if x=0. Return true if successful */
|
||||
mask_t gf_eq(const gf x, const gf y);
|
||||
mask_t gf_lobit(const gf x);
|
||||
mask_t gf_hibit(const gf x);
|
||||
|
||||
void gf_serialize(uint8_t *serial, const gf x, int with_highbit);
|
||||
mask_t gf_deserialize(gf x, const uint8_t serial[SER_BYTES], int with_hibit,
|
||||
uint8_t hi_nmask);
|
||||
|
||||
# include "f_impl.h" /* Bring in the inline implementations */
|
||||
|
||||
# define LIMBPERM(i) (i)
|
||||
# define LIMB_MASK(i) (((1)<<LIMB_PLACE_VALUE(i))-1)
|
||||
|
||||
static const gf ZERO = {{{0}}}, ONE = {{{1}}};
|
||||
|
||||
/* Square x, n times. */
|
||||
static ossl_inline void gf_sqrn(gf_s * RESTRICT y, const gf x, int n)
|
||||
{
|
||||
gf tmp;
|
||||
|
||||
assert(n > 0);
|
||||
if (n & 1) {
|
||||
gf_sqr(y, x);
|
||||
n--;
|
||||
} else {
|
||||
gf_sqr(tmp, x);
|
||||
gf_sqr(y, tmp);
|
||||
n -= 2;
|
||||
}
|
||||
for (; n; n -= 2) {
|
||||
gf_sqr(tmp, y);
|
||||
gf_sqr(y, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
# define gf_add_nr gf_add_RAW
|
||||
|
||||
/* Subtract mod p. Bias by 2 and don't reduce */
|
||||
static ossl_inline void gf_sub_nr(gf c, const gf a, const gf b)
|
||||
{
|
||||
gf_sub_RAW(c, a, b);
|
||||
gf_bias(c, 2);
|
||||
if (GF_HEADROOM < 3)
|
||||
gf_weak_reduce(c);
|
||||
}
|
||||
|
||||
/* Subtract mod p. Bias by amt but don't reduce. */
|
||||
static ossl_inline void gf_subx_nr(gf c, const gf a, const gf b, int amt)
|
||||
{
|
||||
gf_sub_RAW(c, a, b);
|
||||
gf_bias(c, amt);
|
||||
if (GF_HEADROOM < amt + 1)
|
||||
gf_weak_reduce(c);
|
||||
}
|
||||
|
||||
/* Mul by signed int. Not constant-time WRT the sign of that int. */
|
||||
static ossl_inline void gf_mulw(gf c, const gf a, int32_t w)
|
||||
{
|
||||
if (w > 0) {
|
||||
gf_mulw_unsigned(c, a, w);
|
||||
} else {
|
||||
gf_mulw_unsigned(c, a, -w);
|
||||
gf_sub(c, ZERO, c);
|
||||
}
|
||||
}
|
||||
|
||||
/* Constant time, x = is_z ? z : y */
|
||||
static ossl_inline void gf_cond_sel(gf x, const gf y, const gf z, mask_t is_z)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < NLIMBS; i++) {
|
||||
#if ARCH_WORD_BITS == 32
|
||||
x[0].limb[i] = constant_time_select_32(is_z, z[0].limb[i],
|
||||
y[0].limb[i]);
|
||||
#else
|
||||
/* Must be 64 bit */
|
||||
x[0].limb[i] = constant_time_select_64(is_z, z[0].limb[i],
|
||||
y[0].limb[i]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Constant time, if (neg) x=-x; */
|
||||
static ossl_inline void gf_cond_neg(gf x, mask_t neg)
|
||||
{
|
||||
gf y;
|
||||
|
||||
gf_sub(y, ZERO, x);
|
||||
gf_cond_sel(x, x, y, neg);
|
||||
}
|
||||
|
||||
/* Constant time, if (swap) (x,y) = (y,x); */
|
||||
static ossl_inline void gf_cond_swap(gf x, gf_s * RESTRICT y, mask_t swap)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < NLIMBS; i++) {
|
||||
#if ARCH_WORD_BITS == 32
|
||||
constant_time_cond_swap_32(swap, &(x[0].limb[i]), &(y->limb[i]));
|
||||
#else
|
||||
/* Must be 64 bit */
|
||||
constant_time_cond_swap_64(swap, &(x[0].limb[i]), &(y->limb[i]));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HEADER_FIELD_H */
|
||||
@@ -0,0 +1,301 @@
|
||||
/*
|
||||
* Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2015-2016 Cryptography Research, 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 Mike Hamburg
|
||||
*/
|
||||
|
||||
#ifndef HEADER_POINT_448_H
|
||||
# define HEADER_POINT_448_H
|
||||
|
||||
# include "curve448utils.h"
|
||||
# include "field.h"
|
||||
|
||||
/* Comb config: number of combs, n, t, s. */
|
||||
#define COMBS_N 5
|
||||
#define COMBS_T 5
|
||||
#define COMBS_S 18
|
||||
|
||||
/* Projective Niels coordinates */
|
||||
typedef struct {
|
||||
gf a, b, c;
|
||||
} niels_s, niels_t[1];
|
||||
typedef struct {
|
||||
niels_t n;
|
||||
gf z;
|
||||
} pniels_t[1];
|
||||
|
||||
/* Precomputed base */
|
||||
struct curve448_precomputed_s {
|
||||
niels_t table[COMBS_N << (COMBS_T - 1)];
|
||||
};
|
||||
|
||||
# define C448_SCALAR_LIMBS ((446-1)/C448_WORD_BITS+1)
|
||||
|
||||
/* The number of bits in a scalar */
|
||||
# define C448_SCALAR_BITS 446
|
||||
|
||||
/* Number of bytes in a serialized scalar. */
|
||||
# define C448_SCALAR_BYTES 56
|
||||
|
||||
/* X448 encoding ratio. */
|
||||
# define X448_ENCODE_RATIO 2
|
||||
|
||||
/* Number of bytes in an x448 public key */
|
||||
# define X448_PUBLIC_BYTES 56
|
||||
|
||||
/* Number of bytes in an x448 private key */
|
||||
# define X448_PRIVATE_BYTES 56
|
||||
|
||||
/* Twisted Edwards extended homogeneous coordinates */
|
||||
typedef struct curve448_point_s {
|
||||
gf x, y, z, t;
|
||||
} curve448_point_t[1];
|
||||
|
||||
/* Precomputed table based on a point. Can be trivial implementation. */
|
||||
struct curve448_precomputed_s;
|
||||
|
||||
/* Precomputed table based on a point. Can be trivial implementation. */
|
||||
typedef struct curve448_precomputed_s curve448_precomputed_s;
|
||||
|
||||
/* Scalar is stored packed, because we don't need the speed. */
|
||||
typedef struct curve448_scalar_s {
|
||||
c448_word_t limb[C448_SCALAR_LIMBS];
|
||||
} curve448_scalar_t[1];
|
||||
|
||||
/* A scalar equal to 1. */
|
||||
extern const curve448_scalar_t curve448_scalar_one;
|
||||
|
||||
/* A scalar equal to 0. */
|
||||
extern const curve448_scalar_t curve448_scalar_zero;
|
||||
|
||||
/* The identity point on the curve. */
|
||||
extern const curve448_point_t curve448_point_identity;
|
||||
|
||||
/* Precomputed table for the base point on the curve. */
|
||||
extern const struct curve448_precomputed_s *curve448_precomputed_base;
|
||||
extern const niels_t *curve448_wnaf_base;
|
||||
|
||||
/*
|
||||
* Read a scalar from wire format or from bytes.
|
||||
*
|
||||
* ser (in): Serialized form of a scalar.
|
||||
* out (out): Deserialized form.
|
||||
*
|
||||
* Returns:
|
||||
* C448_SUCCESS: The scalar was correctly encoded.
|
||||
* C448_FAILURE: The scalar was greater than the modulus, and has been reduced
|
||||
* modulo that modulus.
|
||||
*/
|
||||
c448_error_t curve448_scalar_decode(curve448_scalar_t out,
|
||||
const unsigned char ser[C448_SCALAR_BYTES]);
|
||||
|
||||
/*
|
||||
* Read a scalar from wire format or from bytes. Reduces mod scalar prime.
|
||||
*
|
||||
* ser (in): Serialized form of a scalar.
|
||||
* ser_len (in): Length of serialized form.
|
||||
* out (out): Deserialized form.
|
||||
*/
|
||||
void curve448_scalar_decode_long(curve448_scalar_t out,
|
||||
const unsigned char *ser, size_t ser_len);
|
||||
|
||||
/*
|
||||
* Serialize a scalar to wire format.
|
||||
*
|
||||
* ser (out): Serialized form of a scalar.
|
||||
* s (in): Deserialized scalar.
|
||||
*/
|
||||
void curve448_scalar_encode(unsigned char ser[C448_SCALAR_BYTES],
|
||||
const curve448_scalar_t s);
|
||||
|
||||
/*
|
||||
* Add two scalars. |a|, |b| and |out| may alias each other.
|
||||
*
|
||||
* a (in): One scalar.
|
||||
* b (in): Another scalar.
|
||||
* out (out): a+b.
|
||||
*/
|
||||
void curve448_scalar_add(curve448_scalar_t out,
|
||||
const curve448_scalar_t a, const curve448_scalar_t b);
|
||||
|
||||
/*
|
||||
* Subtract two scalars. |a|, |b| and |out| may alias each other.
|
||||
* a (in): One scalar.
|
||||
* b (in): Another scalar.
|
||||
* out (out): a-b.
|
||||
*/
|
||||
void curve448_scalar_sub(curve448_scalar_t out,
|
||||
const curve448_scalar_t a, const curve448_scalar_t b);
|
||||
|
||||
/*
|
||||
* Multiply two scalars. |a|, |b| and |out| may alias each other.
|
||||
*
|
||||
* a (in): One scalar.
|
||||
* b (in): Another scalar.
|
||||
* out (out): a*b.
|
||||
*/
|
||||
void curve448_scalar_mul(curve448_scalar_t out,
|
||||
const curve448_scalar_t a, const curve448_scalar_t b);
|
||||
|
||||
/*
|
||||
* Halve a scalar. |a| and |out| may alias each other.
|
||||
*
|
||||
* a (in): A scalar.
|
||||
* out (out): a/2.
|
||||
*/
|
||||
void curve448_scalar_halve(curve448_scalar_t out, const curve448_scalar_t a);
|
||||
|
||||
/*
|
||||
* Copy a scalar. The scalars may alias each other, in which case this
|
||||
* function does nothing.
|
||||
*
|
||||
* a (in): A scalar.
|
||||
* out (out): Will become a copy of a.
|
||||
*/
|
||||
static ossl_inline void curve448_scalar_copy(curve448_scalar_t out,
|
||||
const curve448_scalar_t a)
|
||||
{
|
||||
*out = *a;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy a point. The input and output may alias, in which case this function
|
||||
* does nothing.
|
||||
*
|
||||
* a (out): A copy of the point.
|
||||
* b (in): Any point.
|
||||
*/
|
||||
static ossl_inline void curve448_point_copy(curve448_point_t a,
|
||||
const curve448_point_t b)
|
||||
{
|
||||
*a = *b;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test whether two points are equal. If yes, return C448_TRUE, else return
|
||||
* C448_FALSE.
|
||||
*
|
||||
* a (in): A point.
|
||||
* b (in): Another point.
|
||||
*
|
||||
* Returns:
|
||||
* C448_TRUE: The points are equal.
|
||||
* C448_FALSE: The points are not equal.
|
||||
*/
|
||||
__owur c448_bool_t curve448_point_eq(const curve448_point_t a,
|
||||
const curve448_point_t b);
|
||||
|
||||
/*
|
||||
* Double a point. Equivalent to curve448_point_add(two_a,a,a), but potentially
|
||||
* faster.
|
||||
*
|
||||
* two_a (out): The sum a+a.
|
||||
* a (in): A point.
|
||||
*/
|
||||
void curve448_point_double(curve448_point_t two_a, const curve448_point_t a);
|
||||
|
||||
/*
|
||||
* RFC 7748 Diffie-Hellman scalarmul. This function uses a different
|
||||
* (non-Decaf) encoding.
|
||||
*
|
||||
* out (out): The scaled point base*scalar
|
||||
* base (in): The point to be scaled.
|
||||
* scalar (in): The scalar to multiply by.
|
||||
*
|
||||
* Returns:
|
||||
* C448_SUCCESS: The scalarmul succeeded.
|
||||
* C448_FAILURE: The scalarmul didn't succeed, because the base point is in a
|
||||
* small subgroup.
|
||||
*/
|
||||
__owur c448_error_t x448_int(uint8_t out[X448_PUBLIC_BYTES],
|
||||
const uint8_t base[X448_PUBLIC_BYTES],
|
||||
const uint8_t scalar[X448_PRIVATE_BYTES]);
|
||||
|
||||
/*
|
||||
* Multiply a point by X448_ENCODE_RATIO, then encode it like RFC 7748.
|
||||
*
|
||||
* This function is mainly used internally, but is exported in case
|
||||
* it will be useful.
|
||||
*
|
||||
* The ratio is necessary because the internal representation doesn't
|
||||
* track the cofactor information, so on output we must clear the cofactor.
|
||||
* This would multiply by the cofactor, but in fact internally points are always
|
||||
* even, so it multiplies by half the cofactor instead.
|
||||
*
|
||||
* As it happens, this aligns with the base point definitions; that is,
|
||||
* if you pass the Decaf/Ristretto base point to this function, the result
|
||||
* will be X448_ENCODE_RATIO times the X448
|
||||
* base point.
|
||||
*
|
||||
* out (out): The scaled and encoded point.
|
||||
* p (in): The point to be scaled and encoded.
|
||||
*/
|
||||
void curve448_point_mul_by_ratio_and_encode_like_x448(
|
||||
uint8_t out[X448_PUBLIC_BYTES],
|
||||
const curve448_point_t p);
|
||||
|
||||
/*
|
||||
* RFC 7748 Diffie-Hellman base point scalarmul. This function uses a different
|
||||
* (non-Decaf) encoding.
|
||||
*
|
||||
* out (out): The scaled point base*scalar
|
||||
* scalar (in): The scalar to multiply by.
|
||||
*/
|
||||
void x448_derive_public_key(uint8_t out[X448_PUBLIC_BYTES],
|
||||
const uint8_t scalar[X448_PRIVATE_BYTES]);
|
||||
|
||||
/*
|
||||
* Multiply a precomputed base point by a scalar: out = scalar*base.
|
||||
*
|
||||
* scaled (out): The scaled point base*scalar
|
||||
* base (in): The point to be scaled.
|
||||
* scalar (in): The scalar to multiply by.
|
||||
*/
|
||||
void curve448_precomputed_scalarmul(curve448_point_t scaled,
|
||||
const curve448_precomputed_s * base,
|
||||
const curve448_scalar_t scalar);
|
||||
|
||||
/*
|
||||
* Multiply two base points by two scalars:
|
||||
* combo = scalar1*curve448_point_base + scalar2*base2.
|
||||
*
|
||||
* Otherwise equivalent to curve448_point_double_scalarmul, but may be
|
||||
* faster at the expense of being variable time.
|
||||
*
|
||||
* combo (out): The linear combination scalar1*base + scalar2*base2.
|
||||
* scalar1 (in): A first scalar to multiply by.
|
||||
* base2 (in): A second point to be scaled.
|
||||
* scalar2 (in) A second scalar to multiply by.
|
||||
*
|
||||
* Warning: This function takes variable time, and may leak the scalars used.
|
||||
* It is designed for signature verification.
|
||||
*/
|
||||
void curve448_base_double_scalarmul_non_secret(curve448_point_t combo,
|
||||
const curve448_scalar_t scalar1,
|
||||
const curve448_point_t base2,
|
||||
const curve448_scalar_t scalar2);
|
||||
|
||||
/*
|
||||
* Test that a point is valid, for debugging purposes.
|
||||
*
|
||||
* to_test (in): The point to test.
|
||||
*
|
||||
* Returns:
|
||||
* C448_TRUE The point is valid.
|
||||
* C448_FALSE The point is invalid.
|
||||
*/
|
||||
__owur c448_bool_t curve448_point_valid(const curve448_point_t to_test);
|
||||
|
||||
/* Overwrite scalar with zeros. */
|
||||
void curve448_scalar_destroy(curve448_scalar_t scalar);
|
||||
|
||||
/* Overwrite point with zeros. */
|
||||
void curve448_point_destroy(curve448_point_t point);
|
||||
|
||||
#endif /* HEADER_POINT_448_H */
|
||||
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
* Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2015-2016 Cryptography Research, 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 Mike Hamburg
|
||||
*/
|
||||
#include <openssl/crypto.h>
|
||||
|
||||
#include "word.h"
|
||||
#include "point_448.h"
|
||||
|
||||
static const c448_word_t MONTGOMERY_FACTOR = (c448_word_t) 0x3bd440fae918bc5;
|
||||
static const curve448_scalar_t sc_p = {
|
||||
{
|
||||
{
|
||||
SC_LIMB(0x2378c292ab5844f3), SC_LIMB(0x216cc2728dc58f55),
|
||||
SC_LIMB(0xc44edb49aed63690), SC_LIMB(0xffffffff7cca23e9),
|
||||
SC_LIMB(0xffffffffffffffff), SC_LIMB(0xffffffffffffffff),
|
||||
SC_LIMB(0x3fffffffffffffff)
|
||||
}
|
||||
}
|
||||
}, sc_r2 = {
|
||||
{
|
||||
{
|
||||
|
||||
SC_LIMB(0xe3539257049b9b60), SC_LIMB(0x7af32c4bc1b195d9),
|
||||
SC_LIMB(0x0d66de2388ea1859), SC_LIMB(0xae17cf725ee4d838),
|
||||
SC_LIMB(0x1a9cc14ba3c47c44), SC_LIMB(0x2052bcb7e4d070af),
|
||||
SC_LIMB(0x3402a939f823b729)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#define WBITS C448_WORD_BITS /* NB this may be different from ARCH_WORD_BITS */
|
||||
|
||||
const curve448_scalar_t curve448_scalar_one = {{{1}}};
|
||||
const curve448_scalar_t curve448_scalar_zero = {{{0}}};
|
||||
|
||||
/*
|
||||
* {extra,accum} - sub +? p
|
||||
* Must have extra <= 1
|
||||
*/
|
||||
static void sc_subx(curve448_scalar_t out,
|
||||
const c448_word_t accum[C448_SCALAR_LIMBS],
|
||||
const curve448_scalar_t sub,
|
||||
const curve448_scalar_t p, c448_word_t extra)
|
||||
{
|
||||
c448_dsword_t chain = 0;
|
||||
unsigned int i;
|
||||
c448_word_t borrow;
|
||||
|
||||
for (i = 0; i < C448_SCALAR_LIMBS; i++) {
|
||||
chain = (chain + accum[i]) - sub->limb[i];
|
||||
out->limb[i] = (c448_word_t)chain;
|
||||
chain >>= WBITS;
|
||||
}
|
||||
borrow = (c448_word_t)chain + extra; /* = 0 or -1 */
|
||||
|
||||
chain = 0;
|
||||
for (i = 0; i < C448_SCALAR_LIMBS; i++) {
|
||||
chain = (chain + out->limb[i]) + (p->limb[i] & borrow);
|
||||
out->limb[i] = (c448_word_t)chain;
|
||||
chain >>= WBITS;
|
||||
}
|
||||
}
|
||||
|
||||
static void sc_montmul(curve448_scalar_t out, const curve448_scalar_t a,
|
||||
const curve448_scalar_t b)
|
||||
{
|
||||
unsigned int i, j;
|
||||
c448_word_t accum[C448_SCALAR_LIMBS + 1] = { 0 };
|
||||
c448_word_t hi_carry = 0;
|
||||
|
||||
for (i = 0; i < C448_SCALAR_LIMBS; i++) {
|
||||
c448_word_t mand = a->limb[i];
|
||||
const c448_word_t *mier = b->limb;
|
||||
|
||||
c448_dword_t chain = 0;
|
||||
for (j = 0; j < C448_SCALAR_LIMBS; j++) {
|
||||
chain += ((c448_dword_t) mand) * mier[j] + accum[j];
|
||||
accum[j] = (c448_word_t)chain;
|
||||
chain >>= WBITS;
|
||||
}
|
||||
accum[j] = (c448_word_t)chain;
|
||||
|
||||
mand = accum[0] * MONTGOMERY_FACTOR;
|
||||
chain = 0;
|
||||
mier = sc_p->limb;
|
||||
for (j = 0; j < C448_SCALAR_LIMBS; j++) {
|
||||
chain += (c448_dword_t) mand *mier[j] + accum[j];
|
||||
if (j)
|
||||
accum[j - 1] = (c448_word_t)chain;
|
||||
chain >>= WBITS;
|
||||
}
|
||||
chain += accum[j];
|
||||
chain += hi_carry;
|
||||
accum[j - 1] = (c448_word_t)chain;
|
||||
hi_carry = chain >> WBITS;
|
||||
}
|
||||
|
||||
sc_subx(out, accum, sc_p, sc_p, hi_carry);
|
||||
}
|
||||
|
||||
void curve448_scalar_mul(curve448_scalar_t out, const curve448_scalar_t a,
|
||||
const curve448_scalar_t b)
|
||||
{
|
||||
sc_montmul(out, a, b);
|
||||
sc_montmul(out, out, sc_r2);
|
||||
}
|
||||
|
||||
void curve448_scalar_sub(curve448_scalar_t out, const curve448_scalar_t a,
|
||||
const curve448_scalar_t b)
|
||||
{
|
||||
sc_subx(out, a->limb, b, sc_p, 0);
|
||||
}
|
||||
|
||||
void curve448_scalar_add(curve448_scalar_t out, const curve448_scalar_t a,
|
||||
const curve448_scalar_t b)
|
||||
{
|
||||
c448_dword_t chain = 0;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < C448_SCALAR_LIMBS; i++) {
|
||||
chain = (chain + a->limb[i]) + b->limb[i];
|
||||
out->limb[i] = (c448_word_t)chain;
|
||||
chain >>= WBITS;
|
||||
}
|
||||
sc_subx(out, out->limb, sc_p, sc_p, (c448_word_t)chain);
|
||||
}
|
||||
|
||||
static ossl_inline void scalar_decode_short(curve448_scalar_t s,
|
||||
const unsigned char *ser,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
unsigned int i, j, k = 0;
|
||||
|
||||
for (i = 0; i < C448_SCALAR_LIMBS; i++) {
|
||||
c448_word_t out = 0;
|
||||
|
||||
for (j = 0; j < sizeof(c448_word_t) && k < nbytes; j++, k++)
|
||||
out |= ((c448_word_t) ser[k]) << (8 * j);
|
||||
s->limb[i] = out;
|
||||
}
|
||||
}
|
||||
|
||||
c448_error_t curve448_scalar_decode(
|
||||
curve448_scalar_t s,
|
||||
const unsigned char ser[C448_SCALAR_BYTES])
|
||||
{
|
||||
unsigned int i;
|
||||
c448_dsword_t accum = 0;
|
||||
|
||||
scalar_decode_short(s, ser, C448_SCALAR_BYTES);
|
||||
for (i = 0; i < C448_SCALAR_LIMBS; i++)
|
||||
accum = (accum + s->limb[i] - sc_p->limb[i]) >> WBITS;
|
||||
/* Here accum == 0 or -1 */
|
||||
|
||||
curve448_scalar_mul(s, s, curve448_scalar_one); /* ham-handed reduce */
|
||||
|
||||
return c448_succeed_if(~word_is_zero((uint32_t)accum));
|
||||
}
|
||||
|
||||
void curve448_scalar_destroy(curve448_scalar_t scalar)
|
||||
{
|
||||
OPENSSL_cleanse(scalar, sizeof(curve448_scalar_t));
|
||||
}
|
||||
|
||||
void curve448_scalar_decode_long(curve448_scalar_t s,
|
||||
const unsigned char *ser, size_t ser_len)
|
||||
{
|
||||
size_t i;
|
||||
curve448_scalar_t t1, t2;
|
||||
|
||||
if (ser_len == 0) {
|
||||
curve448_scalar_copy(s, curve448_scalar_zero);
|
||||
return;
|
||||
}
|
||||
|
||||
i = ser_len - (ser_len % C448_SCALAR_BYTES);
|
||||
if (i == ser_len)
|
||||
i -= C448_SCALAR_BYTES;
|
||||
|
||||
scalar_decode_short(t1, &ser[i], ser_len - i);
|
||||
|
||||
if (ser_len == sizeof(curve448_scalar_t)) {
|
||||
assert(i == 0);
|
||||
/* ham-handed reduce */
|
||||
curve448_scalar_mul(s, t1, curve448_scalar_one);
|
||||
curve448_scalar_destroy(t1);
|
||||
return;
|
||||
}
|
||||
|
||||
while (i) {
|
||||
i -= C448_SCALAR_BYTES;
|
||||
sc_montmul(t1, t1, sc_r2);
|
||||
(void)curve448_scalar_decode(t2, ser + i);
|
||||
curve448_scalar_add(t1, t1, t2);
|
||||
}
|
||||
|
||||
curve448_scalar_copy(s, t1);
|
||||
curve448_scalar_destroy(t1);
|
||||
curve448_scalar_destroy(t2);
|
||||
}
|
||||
|
||||
void curve448_scalar_encode(unsigned char ser[C448_SCALAR_BYTES],
|
||||
const curve448_scalar_t s)
|
||||
{
|
||||
unsigned int i, j, k = 0;
|
||||
|
||||
for (i = 0; i < C448_SCALAR_LIMBS; i++) {
|
||||
for (j = 0; j < sizeof(c448_word_t); j++, k++)
|
||||
ser[k] = s->limb[i] >> (8 * j);
|
||||
}
|
||||
}
|
||||
|
||||
void curve448_scalar_halve(curve448_scalar_t out, const curve448_scalar_t a)
|
||||
{
|
||||
c448_word_t mask = 0 - (a->limb[0] & 1);
|
||||
c448_dword_t chain = 0;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < C448_SCALAR_LIMBS; i++) {
|
||||
chain = (chain + a->limb[i]) + (sc_p->limb[i] & mask);
|
||||
out->limb[i] = (c448_word_t)chain;
|
||||
chain >>= C448_WORD_BITS;
|
||||
}
|
||||
for (i = 0; i < C448_SCALAR_LIMBS - 1; i++)
|
||||
out->limb[i] = out->limb[i] >> 1 | out->limb[i + 1] << (WBITS - 1);
|
||||
out->limb[i] = out->limb[i] >> 1 | (c448_word_t)(chain << (WBITS - 1));
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2014 Cryptography Research, 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 Mike Hamburg
|
||||
*/
|
||||
|
||||
#ifndef HEADER_WORD_H
|
||||
# define HEADER_WORD_H
|
||||
|
||||
# include <string.h>
|
||||
# include <assert.h>
|
||||
# include <stdlib.h>
|
||||
# include <openssl/e_os2.h>
|
||||
# include "arch_intrinsics.h"
|
||||
# include "curve448utils.h"
|
||||
|
||||
# if (ARCH_WORD_BITS == 64)
|
||||
typedef uint64_t word_t, mask_t;
|
||||
typedef __uint128_t dword_t;
|
||||
typedef int32_t hsword_t;
|
||||
typedef int64_t sword_t;
|
||||
typedef __int128_t dsword_t;
|
||||
# elif (ARCH_WORD_BITS == 32)
|
||||
typedef uint32_t word_t, mask_t;
|
||||
typedef uint64_t dword_t;
|
||||
typedef int16_t hsword_t;
|
||||
typedef int32_t sword_t;
|
||||
typedef int64_t dsword_t;
|
||||
# else
|
||||
# error "For now, we only support 32- and 64-bit architectures."
|
||||
# endif
|
||||
|
||||
/*
|
||||
* Scalar limbs are keyed off of the API word size instead of the arch word
|
||||
* size.
|
||||
*/
|
||||
# if C448_WORD_BITS == 64
|
||||
# define SC_LIMB(x) (x)
|
||||
# elif C448_WORD_BITS == 32
|
||||
# define SC_LIMB(x) ((uint32_t)(x)),((x) >> 32)
|
||||
# else
|
||||
# error "For now we only support 32- and 64-bit architectures."
|
||||
# endif
|
||||
|
||||
/*
|
||||
* The plan on booleans: The external interface uses c448_bool_t, but this
|
||||
* might be a different size than our particular arch's word_t (and thus
|
||||
* mask_t). Also, the caller isn't guaranteed to pass it as nonzero. So
|
||||
* bool_to_mask converts word sizes and checks nonzero. On the flip side,
|
||||
* mask_t is always -1 or 0, but it might be a different size than
|
||||
* c448_bool_t. On the third hand, we have success vs boolean types, but
|
||||
* that's handled in common.h: it converts between c448_bool_t and
|
||||
* c448_error_t.
|
||||
*/
|
||||
static ossl_inline c448_bool_t mask_to_bool(mask_t m)
|
||||
{
|
||||
return (c448_sword_t)(sword_t)m;
|
||||
}
|
||||
|
||||
static ossl_inline mask_t bool_to_mask(c448_bool_t m)
|
||||
{
|
||||
/* On most arches this will be optimized to a simple cast. */
|
||||
mask_t ret = 0;
|
||||
unsigned int i;
|
||||
unsigned int limit = sizeof(c448_bool_t) / sizeof(mask_t);
|
||||
|
||||
if (limit < 1)
|
||||
limit = 1;
|
||||
for (i = 0; i < limit; i++)
|
||||
ret |= ~word_is_zero(m >> (i * 8 * sizeof(word_t)));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* HEADER_WORD_H */
|
||||
+1
-15
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. 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
|
||||
@@ -7,21 +8,6 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/* ====================================================================
|
||||
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
|
||||
*
|
||||
* The Elliptic Curve Public-Key Crypto Library (ECC Code) included
|
||||
* herein is developed by SUN MICROSYSTEMS, INC., and is contributed
|
||||
* to the OpenSSL project.
|
||||
*
|
||||
* The ECC Code is licensed pursuant to the OpenSSL open source
|
||||
* license provided below.
|
||||
*
|
||||
* The software is originally written by Sheueling Chang Shantz and
|
||||
* Douglas Stebila of Sun Microsystems Laboratories.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "internal/bn_int.h"
|
||||
|
||||
+1
-15
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. 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
|
||||
@@ -7,21 +8,6 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/* ====================================================================
|
||||
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
|
||||
*
|
||||
* The Elliptic Curve Public-Key Crypto Library (ECC Code) included
|
||||
* herein is developed by SUN MICROSYSTEMS, INC., and is contributed
|
||||
* to the OpenSSL project.
|
||||
*
|
||||
* The ECC Code is licensed pursuant to the OpenSSL open source
|
||||
* license provided below.
|
||||
*
|
||||
* The software is originally written by Sheueling Chang Shantz and
|
||||
* Douglas Stebila of Sun Microsystems Laboratories.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "ec_lcl.h"
|
||||
|
||||
+5
-21
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. 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
|
||||
@@ -7,21 +8,6 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/* ====================================================================
|
||||
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
|
||||
*
|
||||
* The Elliptic Curve Public-Key Crypto Library (ECC Code) included
|
||||
* herein is developed by SUN MICROSYSTEMS, INC., and is contributed
|
||||
* to the OpenSSL project.
|
||||
*
|
||||
* The ECC Code is licensed pursuant to the OpenSSL open source
|
||||
* license provided below.
|
||||
*
|
||||
* The software is originally written by Sheueling Chang Shantz and
|
||||
* Douglas Stebila of Sun Microsystems Laboratories.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "internal/bn_int.h"
|
||||
@@ -617,9 +603,9 @@ int ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
|
||||
if (!BN_GF2m_add(lh, lh, y2))
|
||||
goto err;
|
||||
ret = BN_is_zero(lh);
|
||||
|
||||
err:
|
||||
if (ctx)
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
}
|
||||
@@ -670,8 +656,7 @@ int ec_GF2m_simple_cmp(const EC_GROUP *group, const EC_POINT *a,
|
||||
ret = ((BN_cmp(aX, bX) == 0) && BN_cmp(aY, bY) == 0) ? 0 : 1;
|
||||
|
||||
err:
|
||||
if (ctx)
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
}
|
||||
@@ -712,8 +697,7 @@ int ec_GF2m_simple_make_affine(const EC_GROUP *group, EC_POINT *point,
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
if (ctx)
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
+49
-1
@@ -520,6 +520,48 @@ static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
|
||||
|
||||
}
|
||||
|
||||
static int ec_pkey_check(const EVP_PKEY *pkey)
|
||||
{
|
||||
EC_KEY *eckey = pkey->pkey.ec;
|
||||
|
||||
/* stay consistent to what EVP_PKEY_check demands */
|
||||
if (eckey->priv_key == NULL) {
|
||||
ECerr(EC_F_EC_PKEY_CHECK, EC_R_MISSING_PRIVATE_KEY);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return EC_KEY_check_key(eckey);
|
||||
}
|
||||
|
||||
static int ec_pkey_public_check(const EVP_PKEY *pkey)
|
||||
{
|
||||
EC_KEY *eckey = pkey->pkey.ec;
|
||||
|
||||
/*
|
||||
* Note: it unnecessary to check eckey->pub_key here since
|
||||
* it will be checked in EC_KEY_check_key(). In fact, the
|
||||
* EC_KEY_check_key() mainly checks the public key, and checks
|
||||
* the private key optionally (only if there is one). So if
|
||||
* someone passes a whole EC key (public + private), this
|
||||
* will also work...
|
||||
*/
|
||||
|
||||
return EC_KEY_check_key(eckey);
|
||||
}
|
||||
|
||||
static int ec_pkey_param_check(const EVP_PKEY *pkey)
|
||||
{
|
||||
EC_KEY *eckey = pkey->pkey.ec;
|
||||
|
||||
/* stay consistent to what EVP_PKEY_check demands */
|
||||
if (eckey->group == NULL) {
|
||||
ECerr(EC_F_EC_PKEY_PARAM_CHECK, EC_R_MISSING_PARAMETERS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return EC_GROUP_check(eckey->group, NULL);
|
||||
}
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = {
|
||||
EVP_PKEY_EC,
|
||||
EVP_PKEY_EC,
|
||||
@@ -551,7 +593,13 @@ const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = {
|
||||
int_ec_free,
|
||||
ec_pkey_ctrl,
|
||||
old_ec_priv_decode,
|
||||
old_ec_priv_encode
|
||||
old_ec_priv_encode,
|
||||
|
||||
0, 0, 0,
|
||||
|
||||
ec_pkey_check,
|
||||
ec_pkey_public_check,
|
||||
ec_pkey_param_check
|
||||
};
|
||||
|
||||
int EC_KEY_print(BIO *bp, const EC_KEY *x, int off)
|
||||
|
||||
+22
-21
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2002-2018 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
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/asn1t.h>
|
||||
#include <openssl/objects.h>
|
||||
#include "internal/nelem.h"
|
||||
|
||||
int EC_GROUP_get_basis_type(const EC_GROUP *group)
|
||||
{
|
||||
@@ -87,13 +88,13 @@ int EC_GROUP_get_pentanomial_basis(const EC_GROUP *group, unsigned int *k1,
|
||||
|
||||
/* some structures needed for the asn1 encoding */
|
||||
typedef struct x9_62_pentanomial_st {
|
||||
long k1;
|
||||
long k2;
|
||||
long k3;
|
||||
int32_t k1;
|
||||
int32_t k2;
|
||||
int32_t k3;
|
||||
} X9_62_PENTANOMIAL;
|
||||
|
||||
typedef struct x9_62_characteristic_two_st {
|
||||
long m;
|
||||
int32_t m;
|
||||
ASN1_OBJECT *type;
|
||||
union {
|
||||
char *ptr;
|
||||
@@ -128,7 +129,7 @@ typedef struct x9_62_curve_st {
|
||||
} X9_62_CURVE;
|
||||
|
||||
struct ec_parameters_st {
|
||||
long version;
|
||||
int32_t version;
|
||||
X9_62_FIELDID *fieldID;
|
||||
X9_62_CURVE *curve;
|
||||
ASN1_OCTET_STRING *base;
|
||||
@@ -147,7 +148,7 @@ struct ecpk_parameters_st {
|
||||
|
||||
/* SEC1 ECPrivateKey */
|
||||
typedef struct ec_privatekey_st {
|
||||
long version;
|
||||
int32_t version;
|
||||
ASN1_OCTET_STRING *privateKey;
|
||||
ECPKPARAMETERS *parameters;
|
||||
ASN1_BIT_STRING *publicKey;
|
||||
@@ -155,9 +156,9 @@ typedef struct ec_privatekey_st {
|
||||
|
||||
/* the OpenSSL ASN.1 definitions */
|
||||
ASN1_SEQUENCE(X9_62_PENTANOMIAL) = {
|
||||
ASN1_SIMPLE(X9_62_PENTANOMIAL, k1, LONG),
|
||||
ASN1_SIMPLE(X9_62_PENTANOMIAL, k2, LONG),
|
||||
ASN1_SIMPLE(X9_62_PENTANOMIAL, k3, LONG)
|
||||
ASN1_EMBED(X9_62_PENTANOMIAL, k1, INT32),
|
||||
ASN1_EMBED(X9_62_PENTANOMIAL, k2, INT32),
|
||||
ASN1_EMBED(X9_62_PENTANOMIAL, k3, INT32)
|
||||
} static_ASN1_SEQUENCE_END(X9_62_PENTANOMIAL)
|
||||
|
||||
DECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL)
|
||||
@@ -172,7 +173,7 @@ ASN1_ADB(X9_62_CHARACTERISTIC_TWO) = {
|
||||
} ASN1_ADB_END(X9_62_CHARACTERISTIC_TWO, 0, type, 0, &char_two_def_tt, NULL);
|
||||
|
||||
ASN1_SEQUENCE(X9_62_CHARACTERISTIC_TWO) = {
|
||||
ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, m, LONG),
|
||||
ASN1_EMBED(X9_62_CHARACTERISTIC_TWO, m, INT32),
|
||||
ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, type, ASN1_OBJECT),
|
||||
ASN1_ADB_OBJECT(X9_62_CHARACTERISTIC_TWO)
|
||||
} static_ASN1_SEQUENCE_END(X9_62_CHARACTERISTIC_TWO)
|
||||
@@ -199,7 +200,7 @@ ASN1_SEQUENCE(X9_62_CURVE) = {
|
||||
} static_ASN1_SEQUENCE_END(X9_62_CURVE)
|
||||
|
||||
ASN1_SEQUENCE(ECPARAMETERS) = {
|
||||
ASN1_SIMPLE(ECPARAMETERS, version, LONG),
|
||||
ASN1_EMBED(ECPARAMETERS, version, INT32),
|
||||
ASN1_SIMPLE(ECPARAMETERS, fieldID, X9_62_FIELDID),
|
||||
ASN1_SIMPLE(ECPARAMETERS, curve, X9_62_CURVE),
|
||||
ASN1_SIMPLE(ECPARAMETERS, base, ASN1_OCTET_STRING),
|
||||
@@ -221,7 +222,7 @@ DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECPKPARAMETERS, ECPKPARAMETERS)
|
||||
IMPLEMENT_ASN1_FUNCTIONS_const(ECPKPARAMETERS)
|
||||
|
||||
ASN1_SEQUENCE(EC_PRIVATEKEY) = {
|
||||
ASN1_SIMPLE(EC_PRIVATEKEY, version, LONG),
|
||||
ASN1_EMBED(EC_PRIVATEKEY, version, INT32),
|
||||
ASN1_SIMPLE(EC_PRIVATEKEY, privateKey, ASN1_OCTET_STRING),
|
||||
ASN1_EXP_OPT(EC_PRIVATEKEY, parameters, ECPKPARAMETERS, 0),
|
||||
ASN1_EXP_OPT(EC_PRIVATEKEY, publicKey, ASN1_BIT_STRING, 1)
|
||||
@@ -359,7 +360,7 @@ static int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field)
|
||||
|
||||
err:
|
||||
BN_free(tmp);
|
||||
return (ok);
|
||||
return ok;
|
||||
}
|
||||
|
||||
static int ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve)
|
||||
@@ -465,7 +466,7 @@ static int ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve)
|
||||
OPENSSL_free(buffer_2);
|
||||
BN_free(tmp_1);
|
||||
BN_free(tmp_2);
|
||||
return (ok);
|
||||
return ok;
|
||||
}
|
||||
|
||||
ECPARAMETERS *EC_GROUP_get_ecparameters(const EC_GROUP *group,
|
||||
@@ -571,7 +572,7 @@ ECPKPARAMETERS *EC_GROUP_get_ecpkparameters(const EC_GROUP *group,
|
||||
|
||||
if (EC_GROUP_get_asn1_flag(group)) {
|
||||
/*
|
||||
* use the asn1 OID to describe the the elliptic curve parameters
|
||||
* use the asn1 OID to describe the elliptic curve parameters
|
||||
*/
|
||||
tmp = EC_GROUP_get_curve_name(group);
|
||||
if (tmp) {
|
||||
@@ -827,7 +828,7 @@ EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params)
|
||||
BN_free(a);
|
||||
BN_free(b);
|
||||
EC_POINT_free(point);
|
||||
return (ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
EC_GROUP *EC_GROUP_new_from_ecpkparameters(const ECPKPARAMETERS *params)
|
||||
@@ -893,7 +894,7 @@ EC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len)
|
||||
|
||||
ECPKPARAMETERS_free(params);
|
||||
*in = p;
|
||||
return (group);
|
||||
return group;
|
||||
}
|
||||
|
||||
int i2d_ECPKParameters(const EC_GROUP *a, unsigned char **out)
|
||||
@@ -910,7 +911,7 @@ int i2d_ECPKParameters(const EC_GROUP *a, unsigned char **out)
|
||||
return 0;
|
||||
}
|
||||
ECPKPARAMETERS_free(tmp);
|
||||
return (ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* some EC_KEY functions */
|
||||
@@ -985,7 +986,7 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
|
||||
*a = ret;
|
||||
EC_PRIVATEKEY_free(priv_key);
|
||||
*in = p;
|
||||
return (ret);
|
||||
return ret;
|
||||
|
||||
err:
|
||||
if (a == NULL || *a != ret)
|
||||
@@ -1233,5 +1234,5 @@ int ECDSA_size(const EC_KEY *r)
|
||||
i = i2d_ASN1_INTEGER(&bs, NULL);
|
||||
i += i; /* r and s */
|
||||
ret = ASN1_object_size(1, i, V_ASN1_SEQUENCE);
|
||||
return (ret);
|
||||
return ret;
|
||||
}
|
||||
+3
-16
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. 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
|
||||
@@ -7,26 +8,12 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/* ====================================================================
|
||||
* 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 <string.h>
|
||||
#include "ec_lcl.h"
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/obj_mac.h>
|
||||
#include <openssl/opensslconf.h>
|
||||
#include "e_os.h"
|
||||
#include "internal/nelem.h"
|
||||
|
||||
typedef struct {
|
||||
int field_type, /* either NID_X9_62_prime_field or
|
||||
@@ -2217,7 +2204,7 @@ static const struct {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* These curves were added by Annie Yousar <a.yousar@informatik.hu-berlin.de>
|
||||
* These curves were added by Annie Yousar.
|
||||
* For the definition of RFC 5639 curves see
|
||||
* http://www.ietf.org/rfc/rfc5639.txt These curves are generated verifiable
|
||||
* at random, nevertheless the seed is omitted as parameter because the
|
||||
|
||||
+1
-14
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. 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
|
||||
@@ -7,20 +8,6 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/* ====================================================================
|
||||
* 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/err.h>
|
||||
#include "ec_lcl.h"
|
||||
|
||||
|
||||
+283
-224
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2018 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
|
||||
@@ -8,272 +8,332 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/ecerr.h>
|
||||
|
||||
/* BEGIN ERROR CODES */
|
||||
#ifndef OPENSSL_NO_ERR
|
||||
|
||||
# define ERR_FUNC(func) ERR_PACK(ERR_LIB_EC,func,0)
|
||||
# define ERR_REASON(reason) ERR_PACK(ERR_LIB_EC,0,reason)
|
||||
|
||||
static ERR_STRING_DATA EC_str_functs[] = {
|
||||
{ERR_FUNC(EC_F_BN_TO_FELEM), "BN_to_felem"},
|
||||
{ERR_FUNC(EC_F_D2I_ECPARAMETERS), "d2i_ECParameters"},
|
||||
{ERR_FUNC(EC_F_D2I_ECPKPARAMETERS), "d2i_ECPKParameters"},
|
||||
{ERR_FUNC(EC_F_D2I_ECPRIVATEKEY), "d2i_ECPrivateKey"},
|
||||
{ERR_FUNC(EC_F_DO_EC_KEY_PRINT), "do_EC_KEY_print"},
|
||||
{ERR_FUNC(EC_F_ECDH_CMS_DECRYPT), "ecdh_cms_decrypt"},
|
||||
{ERR_FUNC(EC_F_ECDH_CMS_SET_SHARED_INFO), "ecdh_cms_set_shared_info"},
|
||||
{ERR_FUNC(EC_F_ECDH_COMPUTE_KEY), "ECDH_compute_key"},
|
||||
{ERR_FUNC(EC_F_ECDH_SIMPLE_COMPUTE_KEY), "ecdh_simple_compute_key"},
|
||||
{ERR_FUNC(EC_F_ECDSA_DO_SIGN_EX), "ECDSA_do_sign_ex"},
|
||||
{ERR_FUNC(EC_F_ECDSA_DO_VERIFY), "ECDSA_do_verify"},
|
||||
{ERR_FUNC(EC_F_ECDSA_SIGN_EX), "ECDSA_sign_ex"},
|
||||
{ERR_FUNC(EC_F_ECDSA_SIGN_SETUP), "ECDSA_sign_setup"},
|
||||
{ERR_FUNC(EC_F_ECDSA_SIG_NEW), "ECDSA_SIG_new"},
|
||||
{ERR_FUNC(EC_F_ECDSA_VERIFY), "ECDSA_verify"},
|
||||
{ERR_FUNC(EC_F_ECKEY_PARAM2TYPE), "eckey_param2type"},
|
||||
{ERR_FUNC(EC_F_ECKEY_PARAM_DECODE), "eckey_param_decode"},
|
||||
{ERR_FUNC(EC_F_ECKEY_PRIV_DECODE), "eckey_priv_decode"},
|
||||
{ERR_FUNC(EC_F_ECKEY_PRIV_ENCODE), "eckey_priv_encode"},
|
||||
{ERR_FUNC(EC_F_ECKEY_PUB_DECODE), "eckey_pub_decode"},
|
||||
{ERR_FUNC(EC_F_ECKEY_PUB_ENCODE), "eckey_pub_encode"},
|
||||
{ERR_FUNC(EC_F_ECKEY_TYPE2PARAM), "eckey_type2param"},
|
||||
{ERR_FUNC(EC_F_ECPARAMETERS_PRINT), "ECParameters_print"},
|
||||
{ERR_FUNC(EC_F_ECPARAMETERS_PRINT_FP), "ECParameters_print_fp"},
|
||||
{ERR_FUNC(EC_F_ECPKPARAMETERS_PRINT), "ECPKParameters_print"},
|
||||
{ERR_FUNC(EC_F_ECPKPARAMETERS_PRINT_FP), "ECPKParameters_print_fp"},
|
||||
{ERR_FUNC(EC_F_ECP_NISTZ256_GET_AFFINE), "ecp_nistz256_get_affine"},
|
||||
static const ERR_STRING_DATA EC_str_functs[] = {
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_BN_TO_FELEM, 0), "BN_to_felem"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_D2I_ECPARAMETERS, 0), "d2i_ECParameters"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_D2I_ECPKPARAMETERS, 0), "d2i_ECPKParameters"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_D2I_ECPRIVATEKEY, 0), "d2i_ECPrivateKey"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_DO_EC_KEY_PRINT, 0), "do_EC_KEY_print"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_ECDH_CMS_DECRYPT, 0), "ecdh_cms_decrypt"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_ECDH_CMS_SET_SHARED_INFO, 0),
|
||||
"ecdh_cms_set_shared_info"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_ECDH_COMPUTE_KEY, 0), "ECDH_compute_key"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_ECDH_SIMPLE_COMPUTE_KEY, 0),
|
||||
"ecdh_simple_compute_key"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_ECDSA_DO_SIGN_EX, 0), "ECDSA_do_sign_ex"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_ECDSA_DO_VERIFY, 0), "ECDSA_do_verify"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_ECDSA_SIGN_EX, 0), "ECDSA_sign_ex"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_ECDSA_SIGN_SETUP, 0), "ECDSA_sign_setup"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_ECDSA_SIG_NEW, 0), "ECDSA_SIG_new"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_ECDSA_VERIFY, 0), "ECDSA_verify"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_ECD_ITEM_VERIFY, 0), "ecd_item_verify"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_ECKEY_PARAM2TYPE, 0), "eckey_param2type"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_ECKEY_PARAM_DECODE, 0), "eckey_param_decode"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_ECKEY_PRIV_DECODE, 0), "eckey_priv_decode"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_ECKEY_PRIV_ENCODE, 0), "eckey_priv_encode"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_ECKEY_PUB_DECODE, 0), "eckey_pub_decode"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_ECKEY_PUB_ENCODE, 0), "eckey_pub_encode"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_ECKEY_TYPE2PARAM, 0), "eckey_type2param"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_ECPARAMETERS_PRINT, 0), "ECParameters_print"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_ECPARAMETERS_PRINT_FP, 0),
|
||||
"ECParameters_print_fp"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_ECPKPARAMETERS_PRINT, 0),
|
||||
"ECPKParameters_print"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_ECPKPARAMETERS_PRINT_FP, 0),
|
||||
"ECPKParameters_print_fp"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_ECP_NISTZ256_GET_AFFINE, 0),
|
||||
"ecp_nistz256_get_affine"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_ECP_NISTZ256_INV_MOD_ORD, 0),
|
||||
"ecp_nistz256_inv_mod_ord"},
|
||||
{ERR_FUNC(EC_F_ECP_NISTZ256_MULT_PRECOMPUTE),
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_ECP_NISTZ256_MULT_PRECOMPUTE, 0),
|
||||
"ecp_nistz256_mult_precompute"},
|
||||
{ERR_FUNC(EC_F_ECP_NISTZ256_POINTS_MUL), "ecp_nistz256_points_mul"},
|
||||
{ERR_FUNC(EC_F_ECP_NISTZ256_PRE_COMP_NEW), "ecp_nistz256_pre_comp_new"},
|
||||
{ERR_FUNC(EC_F_ECP_NISTZ256_WINDOWED_MUL), "ecp_nistz256_windowed_mul"},
|
||||
{ERR_FUNC(EC_F_ECX_KEY_OP), "ecx_key_op"},
|
||||
{ERR_FUNC(EC_F_ECX_PRIV_ENCODE), "ecx_priv_encode"},
|
||||
{ERR_FUNC(EC_F_ECX_PUB_ENCODE), "ecx_pub_encode"},
|
||||
{ERR_FUNC(EC_F_EC_ASN1_GROUP2CURVE), "ec_asn1_group2curve"},
|
||||
{ERR_FUNC(EC_F_EC_ASN1_GROUP2FIELDID), "ec_asn1_group2fieldid"},
|
||||
{ERR_FUNC(EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY),
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_ECP_NISTZ256_POINTS_MUL, 0),
|
||||
"ecp_nistz256_points_mul"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_ECP_NISTZ256_PRE_COMP_NEW, 0),
|
||||
"ecp_nistz256_pre_comp_new"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_ECP_NISTZ256_WINDOWED_MUL, 0),
|
||||
"ecp_nistz256_windowed_mul"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_ECX_KEY_OP, 0), "ecx_key_op"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_ECX_PRIV_ENCODE, 0), "ecx_priv_encode"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_ECX_PUB_ENCODE, 0), "ecx_pub_encode"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_ASN1_GROUP2CURVE, 0), "ec_asn1_group2curve"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_ASN1_GROUP2FIELDID, 0),
|
||||
"ec_asn1_group2fieldid"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY, 0),
|
||||
"ec_GF2m_montgomery_point_multiply"},
|
||||
{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT),
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT, 0),
|
||||
"ec_GF2m_simple_group_check_discriminant"},
|
||||
{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE),
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE, 0),
|
||||
"ec_GF2m_simple_group_set_curve"},
|
||||
{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_OCT2POINT), "ec_GF2m_simple_oct2point"},
|
||||
{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT2OCT), "ec_GF2m_simple_point2oct"},
|
||||
{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES),
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_OCT2POINT, 0),
|
||||
"ec_GF2m_simple_oct2point"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_POINT2OCT, 0),
|
||||
"ec_GF2m_simple_point2oct"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES, 0),
|
||||
"ec_GF2m_simple_point_get_affine_coordinates"},
|
||||
{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES),
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES, 0),
|
||||
"ec_GF2m_simple_point_set_affine_coordinates"},
|
||||
{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES),
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, 0),
|
||||
"ec_GF2m_simple_set_compressed_coordinates"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_DECODE), "ec_GFp_mont_field_decode"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_ENCODE), "ec_GFp_mont_field_encode"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_MUL), "ec_GFp_mont_field_mul"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE),
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_MONT_FIELD_DECODE, 0),
|
||||
"ec_GFp_mont_field_decode"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_MONT_FIELD_ENCODE, 0),
|
||||
"ec_GFp_mont_field_encode"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_MONT_FIELD_MUL, 0),
|
||||
"ec_GFp_mont_field_mul"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE, 0),
|
||||
"ec_GFp_mont_field_set_to_one"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_SQR), "ec_GFp_mont_field_sqr"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_MONT_GROUP_SET_CURVE),
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_MONT_FIELD_SQR, 0),
|
||||
"ec_GFp_mont_field_sqr"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_MONT_GROUP_SET_CURVE, 0),
|
||||
"ec_GFp_mont_group_set_curve"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE),
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE, 0),
|
||||
"ec_GFp_nistp224_group_set_curve"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_NISTP224_POINTS_MUL), "ec_GFp_nistp224_points_mul"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES),
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NISTP224_POINTS_MUL, 0),
|
||||
"ec_GFp_nistp224_points_mul"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES, 0),
|
||||
"ec_GFp_nistp224_point_get_affine_coordinates"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE),
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE, 0),
|
||||
"ec_GFp_nistp256_group_set_curve"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_NISTP256_POINTS_MUL), "ec_GFp_nistp256_points_mul"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES),
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NISTP256_POINTS_MUL, 0),
|
||||
"ec_GFp_nistp256_points_mul"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES, 0),
|
||||
"ec_GFp_nistp256_point_get_affine_coordinates"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE),
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE, 0),
|
||||
"ec_GFp_nistp521_group_set_curve"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_NISTP521_POINTS_MUL), "ec_GFp_nistp521_points_mul"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES),
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NISTP521_POINTS_MUL, 0),
|
||||
"ec_GFp_nistp521_points_mul"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES, 0),
|
||||
"ec_GFp_nistp521_point_get_affine_coordinates"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_NIST_FIELD_MUL), "ec_GFp_nist_field_mul"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_NIST_FIELD_SQR), "ec_GFp_nist_field_sqr"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_NIST_GROUP_SET_CURVE),
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NIST_FIELD_MUL, 0),
|
||||
"ec_GFp_nist_field_mul"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NIST_FIELD_SQR, 0),
|
||||
"ec_GFp_nist_field_sqr"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_NIST_GROUP_SET_CURVE, 0),
|
||||
"ec_GFp_nist_group_set_curve"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT),
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT, 0),
|
||||
"ec_GFp_simple_group_check_discriminant"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE),
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE, 0),
|
||||
"ec_GFp_simple_group_set_curve"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_SIMPLE_MAKE_AFFINE), "ec_GFp_simple_make_affine"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_SIMPLE_OCT2POINT), "ec_GFp_simple_oct2point"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT2OCT), "ec_GFp_simple_point2oct"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE),
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_MAKE_AFFINE, 0),
|
||||
"ec_GFp_simple_make_affine"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_OCT2POINT, 0),
|
||||
"ec_GFp_simple_oct2point"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_POINT2OCT, 0),
|
||||
"ec_GFp_simple_point2oct"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE, 0),
|
||||
"ec_GFp_simple_points_make_affine"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES),
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES, 0),
|
||||
"ec_GFp_simple_point_get_affine_coordinates"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES),
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES, 0),
|
||||
"ec_GFp_simple_point_set_affine_coordinates"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES),
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, 0),
|
||||
"ec_GFp_simple_set_compressed_coordinates"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_CHECK), "EC_GROUP_check"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_CHECK_DISCRIMINANT),
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_CHECK, 0), "EC_GROUP_check"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_CHECK_DISCRIMINANT, 0),
|
||||
"EC_GROUP_check_discriminant"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_COPY), "EC_GROUP_copy"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_GET_CURVE_GF2M), "EC_GROUP_get_curve_GF2m"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_GET_CURVE_GFP), "EC_GROUP_get_curve_GFp"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_GET_DEGREE), "EC_GROUP_get_degree"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_GET_ECPARAMETERS), "EC_GROUP_get_ecparameters"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_GET_ECPKPARAMETERS),
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_COPY, 0), "EC_GROUP_copy"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_GET_CURVE_GF2M, 0),
|
||||
"EC_GROUP_get_curve_GF2m"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_GET_CURVE_GFP, 0),
|
||||
"EC_GROUP_get_curve_GFp"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_GET_DEGREE, 0), "EC_GROUP_get_degree"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_GET_ECPARAMETERS, 0),
|
||||
"EC_GROUP_get_ecparameters"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_GET_ECPKPARAMETERS, 0),
|
||||
"EC_GROUP_get_ecpkparameters"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS),
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS, 0),
|
||||
"EC_GROUP_get_pentanomial_basis"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS),
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_GET_TRINOMIAL_BASIS, 0),
|
||||
"EC_GROUP_get_trinomial_basis"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_NEW), "EC_GROUP_new"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_NEW_BY_CURVE_NAME), "EC_GROUP_new_by_curve_name"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_NEW_FROM_DATA), "ec_group_new_from_data"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS),
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_NEW, 0), "EC_GROUP_new"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_NEW_BY_CURVE_NAME, 0),
|
||||
"EC_GROUP_new_by_curve_name"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_NEW_FROM_DATA, 0),
|
||||
"ec_group_new_from_data"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, 0),
|
||||
"EC_GROUP_new_from_ecparameters"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS),
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS, 0),
|
||||
"EC_GROUP_new_from_ecpkparameters"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_SET_CURVE_GF2M), "EC_GROUP_set_curve_GF2m"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_SET_CURVE_GFP), "EC_GROUP_set_curve_GFp"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_SET_GENERATOR), "EC_GROUP_set_generator"},
|
||||
{ERR_FUNC(EC_F_EC_KEY_CHECK_KEY), "EC_KEY_check_key"},
|
||||
{ERR_FUNC(EC_F_EC_KEY_COPY), "EC_KEY_copy"},
|
||||
{ERR_FUNC(EC_F_EC_KEY_GENERATE_KEY), "EC_KEY_generate_key"},
|
||||
{ERR_FUNC(EC_F_EC_KEY_NEW), "EC_KEY_new"},
|
||||
{ERR_FUNC(EC_F_EC_KEY_NEW_METHOD), "EC_KEY_new_method"},
|
||||
{ERR_FUNC(EC_F_EC_KEY_OCT2PRIV), "EC_KEY_oct2priv"},
|
||||
{ERR_FUNC(EC_F_EC_KEY_PRINT), "EC_KEY_print"},
|
||||
{ERR_FUNC(EC_F_EC_KEY_PRINT_FP), "EC_KEY_print_fp"},
|
||||
{ERR_FUNC(EC_F_EC_KEY_PRIV2OCT), "EC_KEY_priv2oct"},
|
||||
{ERR_FUNC(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES),
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_SET_CURVE_GF2M, 0),
|
||||
"EC_GROUP_set_curve_GF2m"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_SET_CURVE_GFP, 0),
|
||||
"EC_GROUP_set_curve_GFp"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_SET_GENERATOR, 0),
|
||||
"EC_GROUP_set_generator"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_CHECK_KEY, 0), "EC_KEY_check_key"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_COPY, 0), "EC_KEY_copy"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_GENERATE_KEY, 0), "EC_KEY_generate_key"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_NEW, 0), "EC_KEY_new"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_NEW_METHOD, 0), "EC_KEY_new_method"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_OCT2PRIV, 0), "EC_KEY_oct2priv"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_PRINT, 0), "EC_KEY_print"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_PRINT_FP, 0), "EC_KEY_print_fp"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_PRIV2OCT, 0), "EC_KEY_priv2oct"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES, 0),
|
||||
"EC_KEY_set_public_key_affine_coordinates"},
|
||||
{ERR_FUNC(EC_F_EC_KEY_SIMPLE_CHECK_KEY), "ec_key_simple_check_key"},
|
||||
{ERR_FUNC(EC_F_EC_KEY_SIMPLE_OCT2PRIV), "ec_key_simple_oct2priv"},
|
||||
{ERR_FUNC(EC_F_EC_KEY_SIMPLE_PRIV2OCT), "ec_key_simple_priv2oct"},
|
||||
{ERR_FUNC(EC_F_EC_POINTS_MAKE_AFFINE), "EC_POINTs_make_affine"},
|
||||
{ERR_FUNC(EC_F_EC_POINT_ADD), "EC_POINT_add"},
|
||||
{ERR_FUNC(EC_F_EC_POINT_CMP), "EC_POINT_cmp"},
|
||||
{ERR_FUNC(EC_F_EC_POINT_COPY), "EC_POINT_copy"},
|
||||
{ERR_FUNC(EC_F_EC_POINT_DBL), "EC_POINT_dbl"},
|
||||
{ERR_FUNC(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M),
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_SIMPLE_CHECK_KEY, 0),
|
||||
"ec_key_simple_check_key"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_SIMPLE_OCT2PRIV, 0),
|
||||
"ec_key_simple_oct2priv"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_SIMPLE_PRIV2OCT, 0),
|
||||
"ec_key_simple_priv2oct"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_PKEY_CHECK, 0), "ec_pkey_check"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_PKEY_PARAM_CHECK, 0), "ec_pkey_param_check"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINTS_MAKE_AFFINE, 0),
|
||||
"EC_POINTs_make_affine"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_ADD, 0), "EC_POINT_add"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_CMP, 0), "EC_POINT_cmp"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_COPY, 0), "EC_POINT_copy"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_DBL, 0), "EC_POINT_dbl"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M, 0),
|
||||
"EC_POINT_get_affine_coordinates_GF2m"},
|
||||
{ERR_FUNC(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP),
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP, 0),
|
||||
"EC_POINT_get_affine_coordinates_GFp"},
|
||||
{ERR_FUNC(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP),
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, 0),
|
||||
"EC_POINT_get_Jprojective_coordinates_GFp"},
|
||||
{ERR_FUNC(EC_F_EC_POINT_INVERT), "EC_POINT_invert"},
|
||||
{ERR_FUNC(EC_F_EC_POINT_IS_AT_INFINITY), "EC_POINT_is_at_infinity"},
|
||||
{ERR_FUNC(EC_F_EC_POINT_IS_ON_CURVE), "EC_POINT_is_on_curve"},
|
||||
{ERR_FUNC(EC_F_EC_POINT_MAKE_AFFINE), "EC_POINT_make_affine"},
|
||||
{ERR_FUNC(EC_F_EC_POINT_NEW), "EC_POINT_new"},
|
||||
{ERR_FUNC(EC_F_EC_POINT_OCT2POINT), "EC_POINT_oct2point"},
|
||||
{ERR_FUNC(EC_F_EC_POINT_POINT2OCT), "EC_POINT_point2oct"},
|
||||
{ERR_FUNC(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M),
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_INVERT, 0), "EC_POINT_invert"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_IS_AT_INFINITY, 0),
|
||||
"EC_POINT_is_at_infinity"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_IS_ON_CURVE, 0),
|
||||
"EC_POINT_is_on_curve"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_MAKE_AFFINE, 0),
|
||||
"EC_POINT_make_affine"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_NEW, 0), "EC_POINT_new"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_OCT2POINT, 0), "EC_POINT_oct2point"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_POINT2OCT, 0), "EC_POINT_point2oct"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M, 0),
|
||||
"EC_POINT_set_affine_coordinates_GF2m"},
|
||||
{ERR_FUNC(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP),
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP, 0),
|
||||
"EC_POINT_set_affine_coordinates_GFp"},
|
||||
{ERR_FUNC(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M),
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M, 0),
|
||||
"EC_POINT_set_compressed_coordinates_GF2m"},
|
||||
{ERR_FUNC(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP),
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, 0),
|
||||
"EC_POINT_set_compressed_coordinates_GFp"},
|
||||
{ERR_FUNC(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP),
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, 0),
|
||||
"EC_POINT_set_Jprojective_coordinates_GFp"},
|
||||
{ERR_FUNC(EC_F_EC_POINT_SET_TO_INFINITY), "EC_POINT_set_to_infinity"},
|
||||
{ERR_FUNC(EC_F_EC_PRE_COMP_NEW), "ec_pre_comp_new"},
|
||||
{ERR_FUNC(EC_F_EC_WNAF_MUL), "ec_wNAF_mul"},
|
||||
{ERR_FUNC(EC_F_EC_WNAF_PRECOMPUTE_MULT), "ec_wNAF_precompute_mult"},
|
||||
{ERR_FUNC(EC_F_I2D_ECPARAMETERS), "i2d_ECParameters"},
|
||||
{ERR_FUNC(EC_F_I2D_ECPKPARAMETERS), "i2d_ECPKParameters"},
|
||||
{ERR_FUNC(EC_F_I2D_ECPRIVATEKEY), "i2d_ECPrivateKey"},
|
||||
{ERR_FUNC(EC_F_I2O_ECPUBLICKEY), "i2o_ECPublicKey"},
|
||||
{ERR_FUNC(EC_F_NISTP224_PRE_COMP_NEW), "nistp224_pre_comp_new"},
|
||||
{ERR_FUNC(EC_F_NISTP256_PRE_COMP_NEW), "nistp256_pre_comp_new"},
|
||||
{ERR_FUNC(EC_F_NISTP521_PRE_COMP_NEW), "nistp521_pre_comp_new"},
|
||||
{ERR_FUNC(EC_F_O2I_ECPUBLICKEY), "o2i_ECPublicKey"},
|
||||
{ERR_FUNC(EC_F_OLD_EC_PRIV_DECODE), "old_ec_priv_decode"},
|
||||
{ERR_FUNC(EC_F_OSSL_ECDH_COMPUTE_KEY), "ossl_ecdh_compute_key"},
|
||||
{ERR_FUNC(EC_F_OSSL_ECDSA_SIGN_SIG), "ossl_ecdsa_sign_sig"},
|
||||
{ERR_FUNC(EC_F_OSSL_ECDSA_VERIFY_SIG), "ossl_ecdsa_verify_sig"},
|
||||
{ERR_FUNC(EC_F_PKEY_ECX_DERIVE), "pkey_ecx_derive"},
|
||||
{ERR_FUNC(EC_F_PKEY_EC_CTRL), "pkey_ec_ctrl"},
|
||||
{ERR_FUNC(EC_F_PKEY_EC_CTRL_STR), "pkey_ec_ctrl_str"},
|
||||
{ERR_FUNC(EC_F_PKEY_EC_DERIVE), "pkey_ec_derive"},
|
||||
{ERR_FUNC(EC_F_PKEY_EC_KEYGEN), "pkey_ec_keygen"},
|
||||
{ERR_FUNC(EC_F_PKEY_EC_PARAMGEN), "pkey_ec_paramgen"},
|
||||
{ERR_FUNC(EC_F_PKEY_EC_SIGN), "pkey_ec_sign"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_SET_TO_INFINITY, 0),
|
||||
"EC_POINT_set_to_infinity"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_PRE_COMP_NEW, 0), "ec_pre_comp_new"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_WNAF_MUL, 0), "ec_wNAF_mul"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_WNAF_PRECOMPUTE_MULT, 0),
|
||||
"ec_wNAF_precompute_mult"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_I2D_ECPARAMETERS, 0), "i2d_ECParameters"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_I2D_ECPKPARAMETERS, 0), "i2d_ECPKParameters"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_I2D_ECPRIVATEKEY, 0), "i2d_ECPrivateKey"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_I2O_ECPUBLICKEY, 0), "i2o_ECPublicKey"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_NISTP224_PRE_COMP_NEW, 0),
|
||||
"nistp224_pre_comp_new"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_NISTP256_PRE_COMP_NEW, 0),
|
||||
"nistp256_pre_comp_new"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_NISTP521_PRE_COMP_NEW, 0),
|
||||
"nistp521_pre_comp_new"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_O2I_ECPUBLICKEY, 0), "o2i_ECPublicKey"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_OLD_EC_PRIV_DECODE, 0), "old_ec_priv_decode"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_OSSL_ECDH_COMPUTE_KEY, 0),
|
||||
"ossl_ecdh_compute_key"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_OSSL_ECDSA_SIGN_SIG, 0), "ossl_ecdsa_sign_sig"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_OSSL_ECDSA_VERIFY_SIG, 0),
|
||||
"ossl_ecdsa_verify_sig"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_PKEY_ECD_CTRL, 0), "pkey_ecd_ctrl"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_PKEY_ECD_DIGESTSIGN, 0), "pkey_ecd_digestsign"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_PKEY_ECX_DERIVE, 0), "pkey_ecx_derive"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_CTRL, 0), "pkey_ec_ctrl"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_CTRL_STR, 0), "pkey_ec_ctrl_str"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_DERIVE, 0), "pkey_ec_derive"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_KEYGEN, 0), "pkey_ec_keygen"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_PARAMGEN, 0), "pkey_ec_paramgen"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_SIGN, 0), "pkey_ec_sign"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
static ERR_STRING_DATA EC_str_reasons[] = {
|
||||
{ERR_REASON(EC_R_ASN1_ERROR), "asn1 error"},
|
||||
{ERR_REASON(EC_R_BAD_SIGNATURE), "bad signature"},
|
||||
{ERR_REASON(EC_R_BIGNUM_OUT_OF_RANGE), "bignum out of range"},
|
||||
{ERR_REASON(EC_R_BUFFER_TOO_SMALL), "buffer too small"},
|
||||
{ERR_REASON(EC_R_COORDINATES_OUT_OF_RANGE), "coordinates out of range"},
|
||||
{ERR_REASON(EC_R_CURVE_DOES_NOT_SUPPORT_ECDH),
|
||||
"curve does not support ecdh"},
|
||||
{ERR_REASON(EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING),
|
||||
"curve does not support signing"},
|
||||
{ERR_REASON(EC_R_D2I_ECPKPARAMETERS_FAILURE),
|
||||
"d2i ecpkparameters failure"},
|
||||
{ERR_REASON(EC_R_DECODE_ERROR), "decode error"},
|
||||
{ERR_REASON(EC_R_DISCRIMINANT_IS_ZERO), "discriminant is zero"},
|
||||
{ERR_REASON(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE),
|
||||
"ec group new by name failure"},
|
||||
{ERR_REASON(EC_R_FIELD_TOO_LARGE), "field too large"},
|
||||
{ERR_REASON(EC_R_GF2M_NOT_SUPPORTED), "gf2m not supported"},
|
||||
{ERR_REASON(EC_R_GROUP2PKPARAMETERS_FAILURE),
|
||||
"group2pkparameters failure"},
|
||||
{ERR_REASON(EC_R_I2D_ECPKPARAMETERS_FAILURE),
|
||||
"i2d ecpkparameters failure"},
|
||||
{ERR_REASON(EC_R_INCOMPATIBLE_OBJECTS), "incompatible objects"},
|
||||
{ERR_REASON(EC_R_INVALID_ARGUMENT), "invalid argument"},
|
||||
{ERR_REASON(EC_R_INVALID_COMPRESSED_POINT), "invalid compressed point"},
|
||||
{ERR_REASON(EC_R_INVALID_COMPRESSION_BIT), "invalid compression bit"},
|
||||
{ERR_REASON(EC_R_INVALID_CURVE), "invalid curve"},
|
||||
{ERR_REASON(EC_R_INVALID_DIGEST), "invalid digest"},
|
||||
{ERR_REASON(EC_R_INVALID_DIGEST_TYPE), "invalid digest type"},
|
||||
{ERR_REASON(EC_R_INVALID_ENCODING), "invalid encoding"},
|
||||
{ERR_REASON(EC_R_INVALID_FIELD), "invalid field"},
|
||||
{ERR_REASON(EC_R_INVALID_FORM), "invalid form"},
|
||||
{ERR_REASON(EC_R_INVALID_GROUP_ORDER), "invalid group order"},
|
||||
{ERR_REASON(EC_R_INVALID_KEY), "invalid key"},
|
||||
{ERR_REASON(EC_R_INVALID_OUTPUT_LENGTH), "invalid output length"},
|
||||
{ERR_REASON(EC_R_INVALID_PEER_KEY), "invalid peer key"},
|
||||
{ERR_REASON(EC_R_INVALID_PENTANOMIAL_BASIS), "invalid pentanomial basis"},
|
||||
{ERR_REASON(EC_R_INVALID_PRIVATE_KEY), "invalid private key"},
|
||||
{ERR_REASON(EC_R_INVALID_TRINOMIAL_BASIS), "invalid trinomial basis"},
|
||||
{ERR_REASON(EC_R_KDF_PARAMETER_ERROR), "kdf parameter error"},
|
||||
{ERR_REASON(EC_R_KEYS_NOT_SET), "keys not set"},
|
||||
{ERR_REASON(EC_R_MISSING_PARAMETERS), "missing parameters"},
|
||||
{ERR_REASON(EC_R_MISSING_PRIVATE_KEY), "missing private key"},
|
||||
{ERR_REASON(EC_R_NEED_NEW_SETUP_VALUES), "need new setup values"},
|
||||
{ERR_REASON(EC_R_NOT_A_NIST_PRIME), "not a NIST prime"},
|
||||
{ERR_REASON(EC_R_NOT_IMPLEMENTED), "not implemented"},
|
||||
{ERR_REASON(EC_R_NOT_INITIALIZED), "not initialized"},
|
||||
{ERR_REASON(EC_R_NO_PARAMETERS_SET), "no parameters set"},
|
||||
{ERR_REASON(EC_R_NO_PRIVATE_VALUE), "no private value"},
|
||||
{ERR_REASON(EC_R_OPERATION_NOT_SUPPORTED), "operation not supported"},
|
||||
{ERR_REASON(EC_R_PASSED_NULL_PARAMETER), "passed null parameter"},
|
||||
{ERR_REASON(EC_R_PEER_KEY_ERROR), "peer key error"},
|
||||
{ERR_REASON(EC_R_PKPARAMETERS2GROUP_FAILURE),
|
||||
"pkparameters2group failure"},
|
||||
{ERR_REASON(EC_R_POINT_ARITHMETIC_FAILURE), "point arithmetic failure"},
|
||||
{ERR_REASON(EC_R_POINT_AT_INFINITY), "point at infinity"},
|
||||
{ERR_REASON(EC_R_POINT_IS_NOT_ON_CURVE), "point is not on curve"},
|
||||
{ERR_REASON(EC_R_RANDOM_NUMBER_GENERATION_FAILED),
|
||||
"random number generation failed"},
|
||||
{ERR_REASON(EC_R_SHARED_INFO_ERROR), "shared info error"},
|
||||
{ERR_REASON(EC_R_SLOT_FULL), "slot full"},
|
||||
{ERR_REASON(EC_R_UNDEFINED_GENERATOR), "undefined generator"},
|
||||
{ERR_REASON(EC_R_UNDEFINED_ORDER), "undefined order"},
|
||||
{ERR_REASON(EC_R_UNKNOWN_GROUP), "unknown group"},
|
||||
{ERR_REASON(EC_R_UNKNOWN_ORDER), "unknown order"},
|
||||
{ERR_REASON(EC_R_UNSUPPORTED_FIELD), "unsupported field"},
|
||||
{ERR_REASON(EC_R_WRONG_CURVE_PARAMETERS), "wrong curve parameters"},
|
||||
{ERR_REASON(EC_R_WRONG_ORDER), "wrong order"},
|
||||
static const ERR_STRING_DATA EC_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_ASN1_ERROR), "asn1 error"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_BAD_SIGNATURE), "bad signature"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_BIGNUM_OUT_OF_RANGE), "bignum out of range"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_BUFFER_TOO_SMALL), "buffer too small"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_COORDINATES_OUT_OF_RANGE),
|
||||
"coordinates out of range"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_CURVE_DOES_NOT_SUPPORT_ECDH),
|
||||
"curve does not support ecdh"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING),
|
||||
"curve does not support signing"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_D2I_ECPKPARAMETERS_FAILURE),
|
||||
"d2i ecpkparameters failure"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_DECODE_ERROR), "decode error"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_DISCRIMINANT_IS_ZERO),
|
||||
"discriminant is zero"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_EC_GROUP_NEW_BY_NAME_FAILURE),
|
||||
"ec group new by name failure"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_FIELD_TOO_LARGE), "field too large"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_GF2M_NOT_SUPPORTED), "gf2m not supported"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_GROUP2PKPARAMETERS_FAILURE),
|
||||
"group2pkparameters failure"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_I2D_ECPKPARAMETERS_FAILURE),
|
||||
"i2d ecpkparameters failure"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INCOMPATIBLE_OBJECTS),
|
||||
"incompatible objects"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_ARGUMENT), "invalid argument"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_COMPRESSED_POINT),
|
||||
"invalid compressed point"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_COMPRESSION_BIT),
|
||||
"invalid compression bit"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_CURVE), "invalid curve"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_DIGEST), "invalid digest"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_DIGEST_TYPE), "invalid digest type"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_ENCODING), "invalid encoding"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_FIELD), "invalid field"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_FORM), "invalid form"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_GROUP_ORDER), "invalid group order"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_KEY), "invalid key"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_OUTPUT_LENGTH),
|
||||
"invalid output length"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_PEER_KEY), "invalid peer key"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_PENTANOMIAL_BASIS),
|
||||
"invalid pentanomial basis"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_PRIVATE_KEY), "invalid private key"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_TRINOMIAL_BASIS),
|
||||
"invalid trinomial basis"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_KDF_PARAMETER_ERROR), "kdf parameter error"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_KEYS_NOT_SET), "keys not set"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_MISSING_PARAMETERS), "missing parameters"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_MISSING_PRIVATE_KEY), "missing private key"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_NEED_NEW_SETUP_VALUES),
|
||||
"need new setup values"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_NOT_A_NIST_PRIME), "not a NIST prime"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_NOT_IMPLEMENTED), "not implemented"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_NOT_INITIALIZED), "not initialized"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_NO_PARAMETERS_SET), "no parameters set"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_NO_PRIVATE_VALUE), "no private value"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_OPERATION_NOT_SUPPORTED),
|
||||
"operation not supported"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_PASSED_NULL_PARAMETER),
|
||||
"passed null parameter"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_PEER_KEY_ERROR), "peer key error"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_PKPARAMETERS2GROUP_FAILURE),
|
||||
"pkparameters2group failure"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_POINT_ARITHMETIC_FAILURE),
|
||||
"point arithmetic failure"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_POINT_AT_INFINITY), "point at infinity"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_POINT_IS_NOT_ON_CURVE),
|
||||
"point is not on curve"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_RANDOM_NUMBER_GENERATION_FAILED),
|
||||
"random number generation failed"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_SHARED_INFO_ERROR), "shared info error"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_SLOT_FULL), "slot full"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_UNDEFINED_GENERATOR), "undefined generator"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_UNDEFINED_ORDER), "undefined order"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_UNKNOWN_GROUP), "unknown group"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_UNKNOWN_ORDER), "unknown order"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_UNSUPPORTED_FIELD), "unsupported field"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_WRONG_CURVE_PARAMETERS),
|
||||
"wrong curve parameters"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_WRONG_ORDER), "wrong order"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
@@ -282,10 +342,9 @@ static ERR_STRING_DATA EC_str_reasons[] = {
|
||||
int ERR_load_EC_strings(void)
|
||||
{
|
||||
#ifndef OPENSSL_NO_ERR
|
||||
|
||||
if (ERR_func_error_string(EC_str_functs[0].error) == NULL) {
|
||||
ERR_load_strings(0, EC_str_functs);
|
||||
ERR_load_strings(0, EC_str_reasons);
|
||||
ERR_load_strings_const(EC_str_functs);
|
||||
ERR_load_strings_const(EC_str_reasons);
|
||||
}
|
||||
#endif
|
||||
return 1;
|
||||
|
||||
+12
-12
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2002-2017 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. 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
|
||||
@@ -7,15 +8,10 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/* ====================================================================
|
||||
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
|
||||
* Portions originally developed by SUN MICROSYSTEMS, INC., and
|
||||
* contributed to the OpenSSL project.
|
||||
*/
|
||||
|
||||
#include <internal/cryptlib.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <string.h>
|
||||
#include "ec_lcl.h"
|
||||
#include "internal/refcount.h"
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/engine.h>
|
||||
|
||||
@@ -49,7 +45,7 @@ void EC_KEY_free(EC_KEY *r)
|
||||
if (r == NULL)
|
||||
return;
|
||||
|
||||
CRYPTO_atomic_add(&r->references, -1, &i, r->lock);
|
||||
CRYPTO_DOWN_REF(&r->references, &i, r->lock);
|
||||
REF_PRINT_COUNT("EC_KEY", r);
|
||||
if (i > 0)
|
||||
return;
|
||||
@@ -169,7 +165,7 @@ int EC_KEY_up_ref(EC_KEY *r)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (CRYPTO_atomic_add(&r->references, 1, &i, r->lock) <= 0)
|
||||
if (CRYPTO_UP_REF(&r->references, &i, r->lock) <= 0)
|
||||
return 0;
|
||||
|
||||
REF_PRINT_COUNT("EC_KEY", r);
|
||||
@@ -177,6 +173,11 @@ int EC_KEY_up_ref(EC_KEY *r)
|
||||
return ((i > 1) ? 1 : 0);
|
||||
}
|
||||
|
||||
ENGINE *EC_KEY_get0_engine(const EC_KEY *eckey)
|
||||
{
|
||||
return eckey->engine;
|
||||
}
|
||||
|
||||
int EC_KEY_generate_key(EC_KEY *eckey)
|
||||
{
|
||||
if (eckey == NULL || eckey->group == NULL) {
|
||||
@@ -191,7 +192,6 @@ int EC_KEY_generate_key(EC_KEY *eckey)
|
||||
|
||||
int ossl_ec_key_gen(EC_KEY *eckey)
|
||||
{
|
||||
OPENSSL_assert(eckey->group->meth->keygen != NULL);
|
||||
return eckey->group->meth->keygen(eckey);
|
||||
}
|
||||
|
||||
@@ -218,7 +218,7 @@ int ec_key_simple_generate_key(EC_KEY *eckey)
|
||||
goto err;
|
||||
|
||||
do
|
||||
if (!BN_rand_range(priv_key, order))
|
||||
if (!BN_priv_rand_range(priv_key, order))
|
||||
goto err;
|
||||
while (BN_is_zero(priv_key)) ;
|
||||
|
||||
|
||||
+11
-18
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. 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
|
||||
@@ -7,27 +8,12 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/* ====================================================================
|
||||
* 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 <stdlib.h>
|
||||
|
||||
#include <openssl/obj_mac.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#include "e_os.h"
|
||||
#include "internal/refcount.h"
|
||||
|
||||
#if defined(__SUNPRO_C)
|
||||
# if __SUNPRO_C >= 0x520
|
||||
@@ -264,7 +250,7 @@ struct ec_key_st {
|
||||
BIGNUM *priv_key;
|
||||
unsigned int enc_flag;
|
||||
point_conversion_form_t conv_form;
|
||||
int references;
|
||||
CRYPTO_REF_COUNT references;
|
||||
int flags;
|
||||
CRYPTO_EX_DATA ex_data;
|
||||
CRYPTO_RWLOCK *lock;
|
||||
@@ -609,6 +595,13 @@ int ossl_ecdsa_verify(int type, const unsigned char *dgst, int dgst_len,
|
||||
int ossl_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len,
|
||||
const ECDSA_SIG *sig, EC_KEY *eckey);
|
||||
|
||||
int ED25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len,
|
||||
const uint8_t public_key[32], const uint8_t private_key[32]);
|
||||
int ED25519_verify(const uint8_t *message, size_t message_len,
|
||||
const uint8_t signature[64], const uint8_t public_key[32]);
|
||||
void ED25519_public_from_private(uint8_t out_public_key[32],
|
||||
const uint8_t private_key[32]);
|
||||
|
||||
int X25519(uint8_t out_shared_key[32], const uint8_t private_key[32],
|
||||
const uint8_t peer_public_value[32]);
|
||||
void X25519_public_from_private(uint8_t out_public_value[32],
|
||||
|
||||
+20
-16
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. 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
|
||||
@@ -7,12 +8,6 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/* ====================================================================
|
||||
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
|
||||
* Binary polynomial ECC support in OpenSSL originally developed by
|
||||
* SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
@@ -66,13 +61,13 @@ EC_GROUP *EC_GROUP_new(const EC_METHOD *meth)
|
||||
void EC_pre_comp_free(EC_GROUP *group)
|
||||
{
|
||||
switch (group->pre_comp_type) {
|
||||
default:
|
||||
case PCT_none:
|
||||
break;
|
||||
#ifdef ECP_NISTZ256_REFERENCE_IMPLEMENTATION
|
||||
case PCT_nistz256:
|
||||
#ifdef ECP_NISTZ256_ASM
|
||||
EC_nistz256_pre_comp_free(group->pre_comp.nistz256);
|
||||
break;
|
||||
#endif
|
||||
break;
|
||||
#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
|
||||
case PCT_nistp224:
|
||||
EC_nistp224_pre_comp_free(group->pre_comp.nistp224);
|
||||
@@ -83,6 +78,11 @@ void EC_pre_comp_free(EC_GROUP *group)
|
||||
case PCT_nistp521:
|
||||
EC_nistp521_pre_comp_free(group->pre_comp.nistp521);
|
||||
break;
|
||||
#else
|
||||
case PCT_nistp224:
|
||||
case PCT_nistp256:
|
||||
case PCT_nistp521:
|
||||
break;
|
||||
#endif
|
||||
case PCT_ec:
|
||||
EC_ec_pre_comp_free(group->pre_comp.ec);
|
||||
@@ -143,14 +143,14 @@ int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
|
||||
/* Copy precomputed */
|
||||
dest->pre_comp_type = src->pre_comp_type;
|
||||
switch (src->pre_comp_type) {
|
||||
default:
|
||||
case PCT_none:
|
||||
dest->pre_comp.ec = NULL;
|
||||
break;
|
||||
#ifdef ECP_NISTZ256_REFERENCE_IMPLEMENTATION
|
||||
case PCT_nistz256:
|
||||
#ifdef ECP_NISTZ256_ASM
|
||||
dest->pre_comp.nistz256 = EC_nistz256_pre_comp_dup(src->pre_comp.nistz256);
|
||||
break;
|
||||
#endif
|
||||
break;
|
||||
#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
|
||||
case PCT_nistp224:
|
||||
dest->pre_comp.nistp224 = EC_nistp224_pre_comp_dup(src->pre_comp.nistp224);
|
||||
@@ -161,6 +161,11 @@ int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
|
||||
case PCT_nistp521:
|
||||
dest->pre_comp.nistp521 = EC_nistp521_pre_comp_dup(src->pre_comp.nistp521);
|
||||
break;
|
||||
#else
|
||||
case PCT_nistp224:
|
||||
case PCT_nistp256:
|
||||
case PCT_nistp521:
|
||||
break;
|
||||
#endif
|
||||
case PCT_ec:
|
||||
dest->pre_comp.ec = EC_ec_pre_comp_dup(src->pre_comp.ec);
|
||||
@@ -232,7 +237,7 @@ EC_GROUP *EC_GROUP_dup(const EC_GROUP *a)
|
||||
return NULL;
|
||||
|
||||
if ((t = EC_GROUP_new(a->meth)) == NULL)
|
||||
return (NULL);
|
||||
return NULL;
|
||||
if (!EC_GROUP_copy(t, a))
|
||||
goto err;
|
||||
|
||||
@@ -327,7 +332,6 @@ const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group)
|
||||
|
||||
int EC_GROUP_order_bits(const EC_GROUP *group)
|
||||
{
|
||||
OPENSSL_assert(group->meth->group_order_bits != NULL);
|
||||
return group->meth->group_order_bits(group);
|
||||
}
|
||||
|
||||
@@ -621,7 +625,7 @@ EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group)
|
||||
|
||||
t = EC_POINT_new(group);
|
||||
if (t == NULL)
|
||||
return (NULL);
|
||||
return NULL;
|
||||
r = EC_POINT_copy(t, a);
|
||||
if (!r) {
|
||||
EC_POINT_free(t);
|
||||
|
||||
+6
-10
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2001-2017 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. 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
|
||||
@@ -7,18 +8,13 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/* ====================================================================
|
||||
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
|
||||
* Portions of this software developed by SUN MICROSYSTEMS, INC.,
|
||||
* and contributed to the OpenSSL project.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "internal/cryptlib.h"
|
||||
#include "internal/bn_int.h"
|
||||
#include "ec_lcl.h"
|
||||
#include "internal/refcount.h"
|
||||
|
||||
/*
|
||||
* This file implements the wNAF-based interleaving multi-exponentiation method
|
||||
@@ -42,7 +38,7 @@ struct ec_pre_comp_st {
|
||||
* generator: 'num' pointers to EC_POINT
|
||||
* objects followed by a NULL */
|
||||
size_t num; /* numblocks * 2^(w-1) */
|
||||
int references;
|
||||
CRYPTO_REF_COUNT references;
|
||||
CRYPTO_RWLOCK *lock;
|
||||
};
|
||||
|
||||
@@ -77,7 +73,7 @@ EC_PRE_COMP *EC_ec_pre_comp_dup(EC_PRE_COMP *pre)
|
||||
{
|
||||
int i;
|
||||
if (pre != NULL)
|
||||
CRYPTO_atomic_add(&pre->references, 1, &i, pre->lock);
|
||||
CRYPTO_UP_REF(&pre->references, &i, pre->lock);
|
||||
return pre;
|
||||
}
|
||||
|
||||
@@ -88,7 +84,7 @@ void EC_ec_pre_comp_free(EC_PRE_COMP *pre)
|
||||
if (pre == NULL)
|
||||
return;
|
||||
|
||||
CRYPTO_atomic_add(&pre->references, -1, &i, pre->lock);
|
||||
CRYPTO_DOWN_REF(&pre->references, &i, pre->lock);
|
||||
REF_PRINT_COUNT("EC_ec", pre);
|
||||
if (i > 0)
|
||||
return;
|
||||
|
||||
+1
-6
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. 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
|
||||
@@ -7,12 +8,6 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/* ====================================================================
|
||||
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
|
||||
* Binary polynomial ECC support in OpenSSL originally developed by
|
||||
* SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
|
||||
+1
-15
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. 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
|
||||
@@ -7,21 +8,6 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/* ====================================================================
|
||||
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
|
||||
*
|
||||
* The Elliptic Curve Public-Key Crypto Library (ECC Code) included
|
||||
* herein is developed by SUN MICROSYSTEMS, INC., and is contributed
|
||||
* to the OpenSSL project.
|
||||
*
|
||||
* The ECC Code is licensed pursuant to the OpenSSL open source
|
||||
* license provided below.
|
||||
*
|
||||
* The ECDH software is originally written by Douglas Stebila of
|
||||
* Sun Microsystems Laboratories.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2002-2018 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
|
||||
@@ -20,7 +20,7 @@ int ossl_ecdsa_sign(int type, const unsigned char *dgst, int dlen,
|
||||
const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey)
|
||||
{
|
||||
ECDSA_SIG *s;
|
||||
RAND_seed(dgst, dlen);
|
||||
|
||||
s = ECDSA_do_sign_ex(dgst, dlen, kinv, r, eckey);
|
||||
if (s == NULL) {
|
||||
*siglen = 0;
|
||||
@@ -97,7 +97,7 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in,
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
if (!BN_rand_range(k, order)) {
|
||||
if (!BN_priv_rand_range(k, order)) {
|
||||
ECerr(EC_F_ECDSA_SIGN_SETUP,
|
||||
EC_R_RANDOM_NUMBER_GENERATION_FAILED);
|
||||
goto err;
|
||||
@@ -199,7 +199,7 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in,
|
||||
BN_CTX_free(ctx);
|
||||
EC_POINT_free(tmp_point);
|
||||
BN_clear_free(X);
|
||||
return (ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ossl_ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
|
||||
@@ -301,7 +301,7 @@ ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len,
|
||||
}
|
||||
if (BN_is_zero(s)) {
|
||||
/*
|
||||
* if kinv and r have been supplied by the caller don't to
|
||||
* if kinv and r have been supplied by the caller, don't
|
||||
* generate new kinv and r values
|
||||
*/
|
||||
if (in_kinv != NULL && in_r != NULL) {
|
||||
@@ -344,7 +344,7 @@ int ossl_ecdsa_verify(int type, const unsigned char *dgst, int dgst_len,
|
||||
|
||||
s = ECDSA_SIG_new();
|
||||
if (s == NULL)
|
||||
return (ret);
|
||||
return ret;
|
||||
if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL)
|
||||
goto err;
|
||||
/* Ensure signature uses DER and doesn't have trailing garbage */
|
||||
@@ -355,7 +355,7 @@ int ossl_ecdsa_verify(int type, const unsigned char *dgst, int dgst_len,
|
||||
err:
|
||||
OPENSSL_clear_free(der, derlen);
|
||||
ECDSA_SIG_free(s);
|
||||
return (ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ossl_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len,
|
||||
|
||||
+8
-13
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. 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
|
||||
@@ -7,12 +8,6 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/* ====================================================================
|
||||
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
|
||||
* Portions originally developed by SUN MICROSYSTEMS, INC., and
|
||||
* contributed to the OpenSSL project.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/evp.h>
|
||||
@@ -27,12 +22,12 @@ int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off)
|
||||
|
||||
if ((b = BIO_new(BIO_s_file())) == NULL) {
|
||||
ECerr(EC_F_ECPKPARAMETERS_PRINT_FP, ERR_R_BUF_LIB);
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
BIO_set_fp(b, fp, BIO_NOCLOSE);
|
||||
ret = ECPKParameters_print(b, x, off);
|
||||
BIO_free(b);
|
||||
return (ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off)
|
||||
@@ -42,12 +37,12 @@ int EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off)
|
||||
|
||||
if ((b = BIO_new(BIO_s_file())) == NULL) {
|
||||
ECerr(EC_F_EC_KEY_PRINT_FP, ERR_R_BIO_LIB);
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
BIO_set_fp(b, fp, BIO_NOCLOSE);
|
||||
ret = EC_KEY_print(b, x, off);
|
||||
BIO_free(b);
|
||||
return (ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ECParameters_print_fp(FILE *fp, const EC_KEY *x)
|
||||
@@ -57,12 +52,12 @@ int ECParameters_print_fp(FILE *fp, const EC_KEY *x)
|
||||
|
||||
if ((b = BIO_new(BIO_s_file())) == NULL) {
|
||||
ECerr(EC_F_ECPARAMETERS_PRINT_FP, ERR_R_BIO_LIB);
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
BIO_set_fp(b, fp, BIO_NOCLOSE);
|
||||
ret = ECParameters_print(b, x);
|
||||
BIO_free(b);
|
||||
return (ret);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -231,7 +226,7 @@ int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off)
|
||||
BN_free(b);
|
||||
BN_free(gen);
|
||||
BN_CTX_free(ctx);
|
||||
return (ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int print_bin(BIO *fp, const char *name, const unsigned char *buf,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. 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
|
||||
@@ -7,12 +8,6 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/* ====================================================================
|
||||
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
|
||||
* Portions of this software developed by SUN MICROSYSTEMS, INC.,
|
||||
* and contributed to the OpenSSL project.
|
||||
*/
|
||||
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "ec_lcl.h"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. 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
|
||||
@@ -7,12 +8,6 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/* ====================================================================
|
||||
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
|
||||
* Portions of this software developed by SUN MICROSYSTEMS, INC.,
|
||||
* and contributed to the OpenSSL project.
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
|
||||
+19
-15
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2010-2018 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
|
||||
@@ -40,12 +40,12 @@ NON_EMPTY_TRANSLATION_UNIT
|
||||
# include <openssl/err.h>
|
||||
# include "ec_lcl.h"
|
||||
|
||||
# if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
|
||||
# if defined(__SIZEOF_INT128__) && __SIZEOF_INT128__==16
|
||||
/* even with gcc, the typedef won't work for 32-bit platforms */
|
||||
typedef __uint128_t uint128_t; /* nonstandard; implemented by gcc on 64-bit
|
||||
* platforms */
|
||||
# else
|
||||
# error "Need GCC 3.1 or later to define type uint128_t"
|
||||
# error "Need GCC 4.0 or later to define type uint128_t"
|
||||
# endif
|
||||
|
||||
typedef uint8_t u8;
|
||||
@@ -78,7 +78,7 @@ typedef limb felem[4];
|
||||
typedef widelimb widefelem[7];
|
||||
|
||||
/*
|
||||
* Field element represented as a byte arrary. 28*8 = 224 bits is also the
|
||||
* Field element represented as a byte array. 28*8 = 224 bits is also the
|
||||
* group order size for the elliptic curve, and we also use this type for
|
||||
* scalars for point multiplication.
|
||||
*/
|
||||
@@ -235,7 +235,7 @@ static const felem gmul[2][16][3] = {
|
||||
/* Precomputation for the group generator. */
|
||||
struct nistp224_pre_comp_st {
|
||||
felem g_pre_comp[2][16][3];
|
||||
int references;
|
||||
CRYPTO_REF_COUNT references;
|
||||
CRYPTO_RWLOCK *lock;
|
||||
};
|
||||
|
||||
@@ -1238,7 +1238,7 @@ NISTP224_PRE_COMP *EC_nistp224_pre_comp_dup(NISTP224_PRE_COMP *p)
|
||||
{
|
||||
int i;
|
||||
if (p != NULL)
|
||||
CRYPTO_atomic_add(&p->references, 1, &i, p->lock);
|
||||
CRYPTO_UP_REF(&p->references, &i, p->lock);
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -1249,7 +1249,7 @@ void EC_nistp224_pre_comp_free(NISTP224_PRE_COMP *p)
|
||||
if (p == NULL)
|
||||
return;
|
||||
|
||||
CRYPTO_atomic_add(&p->references, -1, &i, p->lock);
|
||||
CRYPTO_DOWN_REF(&p->references, &i, p->lock);
|
||||
REF_PRINT_COUNT("EC_nistp224", x);
|
||||
if (i > 0)
|
||||
return;
|
||||
@@ -1284,9 +1284,10 @@ int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p,
|
||||
if ((ctx = new_ctx = BN_CTX_new()) == NULL)
|
||||
return 0;
|
||||
BN_CTX_start(ctx);
|
||||
if (((curve_p = BN_CTX_get(ctx)) == NULL) ||
|
||||
((curve_a = BN_CTX_get(ctx)) == NULL) ||
|
||||
((curve_b = BN_CTX_get(ctx)) == NULL))
|
||||
curve_p = BN_CTX_get(ctx);
|
||||
curve_a = BN_CTX_get(ctx);
|
||||
curve_b = BN_CTX_get(ctx);
|
||||
if (curve_b == NULL)
|
||||
goto err;
|
||||
BN_bin2bn(nistp224_curve_params[0], sizeof(felem_bytearray), curve_p);
|
||||
BN_bin2bn(nistp224_curve_params[1], sizeof(felem_bytearray), curve_a);
|
||||
@@ -1415,10 +1416,11 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
if ((ctx = new_ctx = BN_CTX_new()) == NULL)
|
||||
return 0;
|
||||
BN_CTX_start(ctx);
|
||||
if (((x = BN_CTX_get(ctx)) == NULL) ||
|
||||
((y = BN_CTX_get(ctx)) == NULL) ||
|
||||
((z = BN_CTX_get(ctx)) == NULL) ||
|
||||
((tmp_scalar = BN_CTX_get(ctx)) == NULL))
|
||||
x = BN_CTX_get(ctx);
|
||||
y = BN_CTX_get(ctx);
|
||||
z = BN_CTX_get(ctx);
|
||||
tmp_scalar = BN_CTX_get(ctx);
|
||||
if (tmp_scalar == NULL)
|
||||
goto err;
|
||||
|
||||
if (scalar != NULL) {
|
||||
@@ -1598,7 +1600,9 @@ int ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
|
||||
if ((ctx = new_ctx = BN_CTX_new()) == NULL)
|
||||
return 0;
|
||||
BN_CTX_start(ctx);
|
||||
if (((x = BN_CTX_get(ctx)) == NULL) || ((y = BN_CTX_get(ctx)) == NULL))
|
||||
x = BN_CTX_get(ctx);
|
||||
y = BN_CTX_get(ctx);
|
||||
if (y == NULL)
|
||||
goto err;
|
||||
/* get the generator */
|
||||
if (group->generator == NULL)
|
||||
|
||||
+18
-14
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2011-2018 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
|
||||
@@ -41,13 +41,13 @@ NON_EMPTY_TRANSLATION_UNIT
|
||||
# include <openssl/err.h>
|
||||
# include "ec_lcl.h"
|
||||
|
||||
# if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
|
||||
# if defined(__SIZEOF_INT128__) && __SIZEOF_INT128__==16
|
||||
/* even with gcc, the typedef won't work for 32-bit platforms */
|
||||
typedef __uint128_t uint128_t; /* nonstandard; implemented by gcc on 64-bit
|
||||
* platforms */
|
||||
typedef __int128_t int128_t;
|
||||
# else
|
||||
# error "Need GCC 3.1 or later to define type uint128_t"
|
||||
# error "Need GCC 4.0 or later to define type uint128_t"
|
||||
# endif
|
||||
|
||||
typedef uint8_t u8;
|
||||
@@ -1766,7 +1766,7 @@ static void batch_mul(felem x_out, felem y_out, felem z_out,
|
||||
/* Precomputation for the group generator. */
|
||||
struct nistp256_pre_comp_st {
|
||||
smallfelem g_pre_comp[2][16][3];
|
||||
int references;
|
||||
CRYPTO_REF_COUNT references;
|
||||
CRYPTO_RWLOCK *lock;
|
||||
};
|
||||
|
||||
@@ -1856,7 +1856,7 @@ NISTP256_PRE_COMP *EC_nistp256_pre_comp_dup(NISTP256_PRE_COMP *p)
|
||||
{
|
||||
int i;
|
||||
if (p != NULL)
|
||||
CRYPTO_atomic_add(&p->references, 1, &i, p->lock);
|
||||
CRYPTO_UP_REF(&p->references, &i, p->lock);
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -1867,7 +1867,7 @@ void EC_nistp256_pre_comp_free(NISTP256_PRE_COMP *pre)
|
||||
if (pre == NULL)
|
||||
return;
|
||||
|
||||
CRYPTO_atomic_add(&pre->references, -1, &i, pre->lock);
|
||||
CRYPTO_DOWN_REF(&pre->references, &i, pre->lock);
|
||||
REF_PRINT_COUNT("EC_nistp256", x);
|
||||
if (i > 0)
|
||||
return;
|
||||
@@ -1902,9 +1902,10 @@ int ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p,
|
||||
if ((ctx = new_ctx = BN_CTX_new()) == NULL)
|
||||
return 0;
|
||||
BN_CTX_start(ctx);
|
||||
if (((curve_p = BN_CTX_get(ctx)) == NULL) ||
|
||||
((curve_a = BN_CTX_get(ctx)) == NULL) ||
|
||||
((curve_b = BN_CTX_get(ctx)) == NULL))
|
||||
curve_p = BN_CTX_get(ctx);
|
||||
curve_a = BN_CTX_get(ctx);
|
||||
curve_b = BN_CTX_get(ctx);
|
||||
if (curve_b == NULL)
|
||||
goto err;
|
||||
BN_bin2bn(nistp256_curve_params[0], sizeof(felem_bytearray), curve_p);
|
||||
BN_bin2bn(nistp256_curve_params[1], sizeof(felem_bytearray), curve_a);
|
||||
@@ -2034,10 +2035,11 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
if ((ctx = new_ctx = BN_CTX_new()) == NULL)
|
||||
return 0;
|
||||
BN_CTX_start(ctx);
|
||||
if (((x = BN_CTX_get(ctx)) == NULL) ||
|
||||
((y = BN_CTX_get(ctx)) == NULL) ||
|
||||
((z = BN_CTX_get(ctx)) == NULL) ||
|
||||
((tmp_scalar = BN_CTX_get(ctx)) == NULL))
|
||||
x = BN_CTX_get(ctx);
|
||||
y = BN_CTX_get(ctx);
|
||||
z = BN_CTX_get(ctx);
|
||||
tmp_scalar = BN_CTX_get(ctx);
|
||||
if (tmp_scalar == NULL)
|
||||
goto err;
|
||||
|
||||
if (scalar != NULL) {
|
||||
@@ -2224,7 +2226,9 @@ int ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
|
||||
if ((ctx = new_ctx = BN_CTX_new()) == NULL)
|
||||
return 0;
|
||||
BN_CTX_start(ctx);
|
||||
if (((x = BN_CTX_get(ctx)) == NULL) || ((y = BN_CTX_get(ctx)) == NULL))
|
||||
x = BN_CTX_get(ctx);
|
||||
y = BN_CTX_get(ctx);
|
||||
if (y == NULL)
|
||||
goto err;
|
||||
/* get the generator */
|
||||
if (group->generator == NULL)
|
||||
|
||||
+37
-17
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2011-2018 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
|
||||
@@ -40,12 +40,12 @@ NON_EMPTY_TRANSLATION_UNIT
|
||||
# include <openssl/err.h>
|
||||
# include "ec_lcl.h"
|
||||
|
||||
# if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
|
||||
# if defined(__SIZEOF_INT128__) && __SIZEOF_INT128__==16
|
||||
/* even with gcc, the typedef won't work for 32-bit platforms */
|
||||
typedef __uint128_t uint128_t; /* nonstandard; implemented by gcc on 64-bit
|
||||
* platforms */
|
||||
# else
|
||||
# error "Need GCC 3.1 or later to define type uint128_t"
|
||||
# error "Need GCC 4.0 or later to define type uint128_t"
|
||||
# endif
|
||||
|
||||
typedef uint8_t u8;
|
||||
@@ -1156,9 +1156,9 @@ static void copy_conditional(felem out, const felem in, limb mask)
|
||||
* adapted for mixed addition (z2 = 1, or z2 = 0 for the point at infinity).
|
||||
*
|
||||
* 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. */
|
||||
* are equal (while not equal to the point at infinity). See comment below
|
||||
* on constant-time.
|
||||
*/
|
||||
static void point_add(felem x3, felem y3, felem z3,
|
||||
const felem x1, const felem y1, const felem z1,
|
||||
const int mixed, const felem x2, const felem y2,
|
||||
@@ -1252,6 +1252,22 @@ static void point_add(felem x3, felem y3, felem z3,
|
||||
/* ftmp5[i] < 2^61 */
|
||||
|
||||
if (x_equal && y_equal && !z1_is_zero && !z2_is_zero) {
|
||||
/*
|
||||
* This is obviously not constant-time but it will almost-never happen
|
||||
* for ECDH / ECDSA. The case where it can happen is during scalar-mult
|
||||
* where the intermediate value gets very close to the group order.
|
||||
* Since |ec_GFp_nistp_recode_scalar_bits| produces signed digits for
|
||||
* the scalar, it's possible for the intermediate value to be a small
|
||||
* negative multiple of the base point, and for the final signed digit
|
||||
* to be the same value. We believe that this only occurs for the scalar
|
||||
* 1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
* ffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb
|
||||
* 71e913863f7, in that case the penultimate intermediate is -9G and
|
||||
* the final digit is also -9G. Since this only happens for a single
|
||||
* scalar, the timing leak is irrelevent. (Any attacker who wanted to
|
||||
* check whether a secret scalar was that exact value, can already do
|
||||
* so.)
|
||||
*/
|
||||
point_double(x3, y3, z3, x1, y1, z1);
|
||||
return;
|
||||
}
|
||||
@@ -1587,7 +1603,7 @@ static void batch_mul(felem x_out, felem y_out, felem z_out,
|
||||
/* Precomputation for the group generator. */
|
||||
struct nistp521_pre_comp_st {
|
||||
felem g_pre_comp[16][3];
|
||||
int references;
|
||||
CRYPTO_REF_COUNT references;
|
||||
CRYPTO_RWLOCK *lock;
|
||||
};
|
||||
|
||||
@@ -1677,7 +1693,7 @@ NISTP521_PRE_COMP *EC_nistp521_pre_comp_dup(NISTP521_PRE_COMP *p)
|
||||
{
|
||||
int i;
|
||||
if (p != NULL)
|
||||
CRYPTO_atomic_add(&p->references, 1, &i, p->lock);
|
||||
CRYPTO_UP_REF(&p->references, &i, p->lock);
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -1688,7 +1704,7 @@ void EC_nistp521_pre_comp_free(NISTP521_PRE_COMP *p)
|
||||
if (p == NULL)
|
||||
return;
|
||||
|
||||
CRYPTO_atomic_add(&p->references, -1, &i, p->lock);
|
||||
CRYPTO_DOWN_REF(&p->references, &i, p->lock);
|
||||
REF_PRINT_COUNT("EC_nistp521", x);
|
||||
if (i > 0)
|
||||
return;
|
||||
@@ -1723,9 +1739,10 @@ int ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p,
|
||||
if ((ctx = new_ctx = BN_CTX_new()) == NULL)
|
||||
return 0;
|
||||
BN_CTX_start(ctx);
|
||||
if (((curve_p = BN_CTX_get(ctx)) == NULL) ||
|
||||
((curve_a = BN_CTX_get(ctx)) == NULL) ||
|
||||
((curve_b = BN_CTX_get(ctx)) == NULL))
|
||||
curve_p = BN_CTX_get(ctx);
|
||||
curve_a = BN_CTX_get(ctx);
|
||||
curve_b = BN_CTX_get(ctx);
|
||||
if (curve_b == NULL)
|
||||
goto err;
|
||||
BN_bin2bn(nistp521_curve_params[0], sizeof(felem_bytearray), curve_p);
|
||||
BN_bin2bn(nistp521_curve_params[1], sizeof(felem_bytearray), curve_a);
|
||||
@@ -1854,10 +1871,11 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
if ((ctx = new_ctx = BN_CTX_new()) == NULL)
|
||||
return 0;
|
||||
BN_CTX_start(ctx);
|
||||
if (((x = BN_CTX_get(ctx)) == NULL) ||
|
||||
((y = BN_CTX_get(ctx)) == NULL) ||
|
||||
((z = BN_CTX_get(ctx)) == NULL) ||
|
||||
((tmp_scalar = BN_CTX_get(ctx)) == NULL))
|
||||
x = BN_CTX_get(ctx);
|
||||
y = BN_CTX_get(ctx);
|
||||
z = BN_CTX_get(ctx);
|
||||
tmp_scalar = BN_CTX_get(ctx);
|
||||
if (tmp_scalar == NULL)
|
||||
goto err;
|
||||
|
||||
if (scalar != NULL) {
|
||||
@@ -2041,7 +2059,9 @@ int ec_GFp_nistp521_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
|
||||
if ((ctx = new_ctx = BN_CTX_new()) == NULL)
|
||||
return 0;
|
||||
BN_CTX_start(ctx);
|
||||
if (((x = BN_CTX_get(ctx)) == NULL) || ((y = BN_CTX_get(ctx)) == NULL))
|
||||
x = BN_CTX_get(ctx);
|
||||
y = BN_CTX_get(ctx);
|
||||
if (y == NULL)
|
||||
goto err;
|
||||
/* get the generator */
|
||||
if (group->generator == NULL)
|
||||
|
||||
+29
-37
@@ -1,47 +1,29 @@
|
||||
/*
|
||||
* Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2014-2018 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"
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* *
|
||||
* Copyright 2014 Intel Corporation *
|
||||
* *
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); *
|
||||
* you may not use this file except in compliance with the License. *
|
||||
* You may obtain a copy of the License at *
|
||||
* *
|
||||
* http://www.apache.org/licenses/LICENSE-2.0 *
|
||||
* *
|
||||
* Unless required by applicable law or agreed to in writing, software *
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, *
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* *
|
||||
******************************************************************************
|
||||
* *
|
||||
* Developers and authors: *
|
||||
* Shay Gueron (1, 2), and Vlad Krasnov (1) *
|
||||
* (1) Intel Corporation, Israel Development Center *
|
||||
* (2) University of Haifa *
|
||||
* (3) CloudFlare, Inc. *
|
||||
* Reference: *
|
||||
* S.Gueron and V.Krasnov, "Fast Prime Field Elliptic Curve Cryptography with *
|
||||
* 256 Bit Primes" *
|
||||
* *
|
||||
******************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "internal/cryptlib.h"
|
||||
#include "internal/bn_int.h"
|
||||
#include "ec_lcl.h"
|
||||
#include "internal/refcount.h"
|
||||
|
||||
#if BN_BITS2 != 64
|
||||
# define TOBN(hi,lo) lo,hi
|
||||
@@ -86,7 +68,7 @@ struct nistz256_pre_comp_st {
|
||||
*/
|
||||
PRECOMP256_ROW *precomp;
|
||||
void *precomp_storage;
|
||||
int references;
|
||||
CRYPTO_REF_COUNT references;
|
||||
CRYPTO_RWLOCK *lock;
|
||||
};
|
||||
|
||||
@@ -256,6 +238,16 @@ static BN_ULONG is_one(const BIGNUM *z)
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* For reference, this macro is used only when new ecp_nistz256 assembly
|
||||
* module is being developed. For example, configure with
|
||||
* -DECP_NISTZ256_REFERENCE_IMPLEMENTATION and implement only functions
|
||||
* performing simplest arithmetic operations on 256-bit vectors. Then
|
||||
* work on implementation of higher-level functions performing point
|
||||
* operations. Then remove ECP_NISTZ256_REFERENCE_IMPLEMENTATION
|
||||
* and never define it again. (The correct macro denoting presence of
|
||||
* ecp_nistz256 module is ECP_NISTZ256_ASM.)
|
||||
*/
|
||||
#ifndef ECP_NISTZ256_REFERENCE_IMPLEMENTATION
|
||||
void ecp_nistz256_point_double(P256_POINT *r, const P256_POINT *a);
|
||||
void ecp_nistz256_point_add(P256_POINT *r,
|
||||
@@ -1469,7 +1461,7 @@ NISTZ256_PRE_COMP *EC_nistz256_pre_comp_dup(NISTZ256_PRE_COMP *p)
|
||||
{
|
||||
int i;
|
||||
if (p != NULL)
|
||||
CRYPTO_atomic_add(&p->references, 1, &i, p->lock);
|
||||
CRYPTO_UP_REF(&p->references, &i, p->lock);
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -1480,7 +1472,7 @@ void EC_nistz256_pre_comp_free(NISTZ256_PRE_COMP *pre)
|
||||
if (pre == NULL)
|
||||
return;
|
||||
|
||||
CRYPTO_atomic_add(&pre->references, -1, &i, pre->lock);
|
||||
CRYPTO_DOWN_REF(&pre->references, &i, pre->lock);
|
||||
REF_PRINT_COUNT("EC_nistz256", x);
|
||||
if (i > 0)
|
||||
return;
|
||||
@@ -1538,6 +1530,10 @@ static int ecp_nistz256_inv_mod_ord(const EC_GROUP *group, BIGNUM *r,
|
||||
BN_ULONG table[15][P256_LIMBS];
|
||||
BN_ULONG out[P256_LIMBS], t[P256_LIMBS];
|
||||
int i, ret = 0;
|
||||
enum {
|
||||
i_1 = 0, i_10, i_11, i_101, i_111, i_1010, i_1111,
|
||||
i_10101, i_101010, i_101111, i_x6, i_x8, i_x16, i_x32
|
||||
};
|
||||
|
||||
/*
|
||||
* Catch allocation failure early.
|
||||
@@ -1615,10 +1611,6 @@ static int ecp_nistz256_inv_mod_ord(const EC_GROUP *group, BIGNUM *r,
|
||||
* multiplications, 25%, on grand scale sign operation is not that
|
||||
* much faster, not more that 2%...
|
||||
*/
|
||||
enum {
|
||||
i_1 = 0, i_10, i_11, i_101, i_111, i_1010, i_1111,
|
||||
i_10101, i_101010, i_101111, i_x6, i_x8, i_x16, i_x32
|
||||
};
|
||||
|
||||
/* pre-calculate powers */
|
||||
ecp_nistz256_ord_sqr_mont(table[i_10], table[i_1], 1);
|
||||
|
||||
+2
-7
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. 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
|
||||
@@ -7,12 +8,6 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/* ====================================================================
|
||||
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
|
||||
* Portions of this software developed by SUN MICROSYSTEMS, INC.,
|
||||
* and contributed to the OpenSSL project.
|
||||
*/
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/symhacks.h>
|
||||
|
||||
@@ -130,7 +125,7 @@ int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group,
|
||||
EC_R_INVALID_COMPRESSION_BIT);
|
||||
else
|
||||
/*
|
||||
* BN_mod_sqrt() should have cought this error (not a square)
|
||||
* BN_mod_sqrt() should have caught this error (not a square)
|
||||
*/
|
||||
ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES,
|
||||
EC_R_INVALID_COMPRESSED_POINT);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2001-2017 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. 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
|
||||
@@ -7,12 +8,6 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/* ====================================================================
|
||||
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
|
||||
* Portions of this software developed by SUN MICROSYSTEMS, INC.,
|
||||
* and contributed to the OpenSSL project.
|
||||
*/
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/symhacks.h>
|
||||
|
||||
@@ -1218,7 +1213,7 @@ int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num,
|
||||
BN_CTX_start(ctx);
|
||||
tmp = BN_CTX_get(ctx);
|
||||
tmp_Z = BN_CTX_get(ctx);
|
||||
if (tmp == NULL || tmp_Z == NULL)
|
||||
if (tmp_Z == NULL)
|
||||
goto err;
|
||||
|
||||
prod_Z = OPENSSL_malloc(num * sizeof(prod_Z[0]));
|
||||
|
||||
+167
-18
@@ -20,6 +20,8 @@
|
||||
#define X25519_BITS 253
|
||||
#define X25519_SECURITY_BITS 128
|
||||
|
||||
#define ED25519_SIGSIZE 64
|
||||
|
||||
typedef struct {
|
||||
unsigned char pubkey[X25519_KEYLEN];
|
||||
unsigned char *privkey;
|
||||
@@ -32,7 +34,7 @@ typedef enum {
|
||||
} ecx_key_op_t;
|
||||
|
||||
/* Setup EVP_PKEY using public, private or generation */
|
||||
static int ecx_key_op(EVP_PKEY *pkey, const X509_ALGOR *palg,
|
||||
static int ecx_key_op(EVP_PKEY *pkey, int id, const X509_ALGOR *palg,
|
||||
const unsigned char *p, int plen, ecx_key_op_t op)
|
||||
{
|
||||
X25519_KEY *xkey;
|
||||
@@ -76,16 +78,21 @@ static int ecx_key_op(EVP_PKEY *pkey, const X509_ALGOR *palg,
|
||||
OPENSSL_free(xkey);
|
||||
return 0;
|
||||
}
|
||||
xkey->privkey[0] &= 248;
|
||||
xkey->privkey[31] &= 127;
|
||||
xkey->privkey[31] |= 64;
|
||||
if (id == EVP_PKEY_X25519) {
|
||||
xkey->privkey[0] &= 248;
|
||||
xkey->privkey[31] &= 127;
|
||||
xkey->privkey[31] |= 64;
|
||||
}
|
||||
} else {
|
||||
memcpy(xkey->privkey, p, X25519_KEYLEN);
|
||||
}
|
||||
X25519_public_from_private(xkey->pubkey, xkey->privkey);
|
||||
if (id == EVP_PKEY_X25519)
|
||||
X25519_public_from_private(xkey->pubkey, xkey->privkey);
|
||||
else
|
||||
ED25519_public_from_private(xkey->pubkey, xkey->privkey);
|
||||
}
|
||||
|
||||
EVP_PKEY_assign(pkey, NID_X25519, xkey);
|
||||
EVP_PKEY_assign(pkey, id, xkey);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -105,8 +112,8 @@ static int ecx_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!X509_PUBKEY_set0_param(pk, OBJ_nid2obj(NID_X25519), V_ASN1_UNDEF,
|
||||
NULL, penc, X25519_KEYLEN)) {
|
||||
if (!X509_PUBKEY_set0_param(pk, OBJ_nid2obj(pkey->ameth->pkey_id),
|
||||
V_ASN1_UNDEF, NULL, penc, X25519_KEYLEN)) {
|
||||
OPENSSL_free(penc);
|
||||
ECerr(EC_F_ECX_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
@@ -122,7 +129,8 @@ static int ecx_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
|
||||
|
||||
if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
|
||||
return 0;
|
||||
return ecx_key_op(pkey, palg, p, pklen, X25519_PUBLIC);
|
||||
return ecx_key_op(pkey, pkey->ameth->pkey_id, palg, p, pklen,
|
||||
X25519_PUBLIC);
|
||||
}
|
||||
|
||||
static int ecx_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
|
||||
@@ -155,7 +163,7 @@ static int ecx_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
|
||||
plen = ASN1_STRING_length(oct);
|
||||
}
|
||||
|
||||
rv = ecx_key_op(pkey, palg, p, plen, X25519_PRIVATE);
|
||||
rv = ecx_key_op(pkey, pkey->ameth->pkey_id, palg, p, plen, X25519_PRIVATE);
|
||||
ASN1_OCTET_STRING_free(oct);
|
||||
return rv;
|
||||
}
|
||||
@@ -182,7 +190,7 @@ static int ecx_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X25519), 0,
|
||||
if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(pkey->ameth->pkey_id), 0,
|
||||
V_ASN1_UNDEF, NULL, penc, penclen)) {
|
||||
OPENSSL_clear_free(penc, penclen);
|
||||
ECerr(EC_F_ECX_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
|
||||
@@ -227,13 +235,15 @@ static int ecx_key_print(BIO *bp, const EVP_PKEY *pkey, int indent,
|
||||
{
|
||||
const X25519_KEY *xkey = pkey->pkey.ptr;
|
||||
|
||||
const char *nm = OBJ_nid2ln(pkey->ameth->pkey_id);
|
||||
|
||||
if (op == X25519_PRIVATE) {
|
||||
if (xkey == NULL || xkey->privkey == NULL) {
|
||||
if (BIO_printf(bp, "%*s<INVALID PRIVATE KEY>\n", indent, "") <= 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
if (BIO_printf(bp, "%*sX25519 Private-Key:\n", indent, "") <= 0)
|
||||
if (BIO_printf(bp, "%*s%s Private-Key:\n", indent, "", nm) <= 0)
|
||||
return 0;
|
||||
if (BIO_printf(bp, "%*spriv:\n", indent, "") <= 0)
|
||||
return 0;
|
||||
@@ -245,7 +255,7 @@ static int ecx_key_print(BIO *bp, const EVP_PKEY *pkey, int indent,
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
if (BIO_printf(bp, "%*sX25519 Public-Key:\n", indent, "") <= 0)
|
||||
if (BIO_printf(bp, "%*s%s Public-Key:\n", indent, "", nm) <= 0)
|
||||
return 0;
|
||||
}
|
||||
if (BIO_printf(bp, "%*spub:\n", indent, "") <= 0)
|
||||
@@ -272,7 +282,8 @@ static int ecx_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
|
||||
switch (op) {
|
||||
|
||||
case ASN1_PKEY_CTRL_SET1_TLS_ENCPT:
|
||||
return ecx_key_op(pkey, NULL, arg2, arg1, X25519_PUBLIC);
|
||||
return ecx_key_op(pkey, EVP_PKEY_X25519, NULL, arg2, arg1,
|
||||
X25519_PUBLIC);
|
||||
|
||||
case ASN1_PKEY_CTRL_GET1_TLS_ENCPT:
|
||||
if (pkey->pkey.ptr != NULL) {
|
||||
@@ -295,8 +306,8 @@ static int ecx_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
|
||||
}
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = {
|
||||
NID_X25519,
|
||||
NID_X25519,
|
||||
EVP_PKEY_X25519,
|
||||
EVP_PKEY_X25519,
|
||||
0,
|
||||
"X25519",
|
||||
"OpenSSL X25519 algorithm",
|
||||
@@ -324,9 +335,87 @@ const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = {
|
||||
NULL
|
||||
};
|
||||
|
||||
static int ecd_size(const EVP_PKEY *pkey)
|
||||
{
|
||||
return ED25519_SIGSIZE;
|
||||
}
|
||||
|
||||
static int ecd_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
|
||||
X509_ALGOR *sigalg, ASN1_BIT_STRING *str,
|
||||
EVP_PKEY *pkey)
|
||||
{
|
||||
const ASN1_OBJECT *obj;
|
||||
int ptype;
|
||||
|
||||
X509_ALGOR_get0(&obj, &ptype, NULL, sigalg);
|
||||
/* Sanity check: make sure it is ED25519 with absent parameters */
|
||||
if (OBJ_obj2nid(obj) != NID_ED25519 || ptype != V_ASN1_UNDEF) {
|
||||
ECerr(EC_F_ECD_ITEM_VERIFY, EC_R_INVALID_ENCODING);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!EVP_DigestVerifyInit(ctx, NULL, NULL, NULL, pkey))
|
||||
return 0;
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int ecd_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
|
||||
X509_ALGOR *alg1, X509_ALGOR *alg2,
|
||||
ASN1_BIT_STRING *str)
|
||||
{
|
||||
/* Set algorithms identifiers */
|
||||
X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
|
||||
if (alg2)
|
||||
X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
|
||||
/* Algorithm idetifiers set: carry on as normal */
|
||||
return 3;
|
||||
}
|
||||
|
||||
static int ecd_sig_info_set(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
|
||||
const ASN1_STRING *sig)
|
||||
{
|
||||
X509_SIG_INFO_set(siginf, NID_undef, NID_ED25519, X25519_SECURITY_BITS,
|
||||
X509_SIG_INFO_TLS);
|
||||
return 1;
|
||||
}
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = {
|
||||
EVP_PKEY_ED25519,
|
||||
EVP_PKEY_ED25519,
|
||||
0,
|
||||
"ED25519",
|
||||
"OpenSSL ED25519 algorithm",
|
||||
|
||||
ecx_pub_decode,
|
||||
ecx_pub_encode,
|
||||
ecx_pub_cmp,
|
||||
ecx_pub_print,
|
||||
|
||||
ecx_priv_decode,
|
||||
ecx_priv_encode,
|
||||
ecx_priv_print,
|
||||
|
||||
ecd_size,
|
||||
ecx_bits,
|
||||
ecx_security_bits,
|
||||
|
||||
0, 0, 0, 0,
|
||||
ecx_cmp_parameters,
|
||||
0, 0,
|
||||
|
||||
ecx_free,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
ecd_item_verify,
|
||||
ecd_item_sign,
|
||||
ecd_sig_info_set
|
||||
};
|
||||
|
||||
static int pkey_ecx_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
|
||||
{
|
||||
return ecx_key_op(pkey, NULL, NULL, 0, X25519_KEYGEN);
|
||||
return ecx_key_op(pkey, ctx->pmeth->pkey_id, NULL, NULL, 0, X25519_KEYGEN);
|
||||
}
|
||||
|
||||
static int pkey_ecx_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
|
||||
@@ -363,7 +452,7 @@ static int pkey_ecx_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
}
|
||||
|
||||
const EVP_PKEY_METHOD ecx25519_pkey_meth = {
|
||||
NID_X25519,
|
||||
EVP_PKEY_X25519,
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
pkey_ecx_keygen,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
@@ -371,3 +460,63 @@ const EVP_PKEY_METHOD ecx25519_pkey_meth = {
|
||||
pkey_ecx_ctrl,
|
||||
0
|
||||
};
|
||||
|
||||
static int pkey_ecd_digestsign(EVP_MD_CTX *ctx, unsigned char *sig,
|
||||
size_t *siglen, const unsigned char *tbs,
|
||||
size_t tbslen)
|
||||
{
|
||||
const X25519_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ptr;
|
||||
|
||||
if (sig == NULL) {
|
||||
*siglen = ED25519_SIGSIZE;
|
||||
return 1;
|
||||
}
|
||||
if (*siglen < ED25519_SIGSIZE) {
|
||||
ECerr(EC_F_PKEY_ECD_DIGESTSIGN, EC_R_BUFFER_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ED25519_sign(sig, tbs, tbslen, edkey->pubkey, edkey->privkey) == 0)
|
||||
return 0;
|
||||
*siglen = ED25519_SIGSIZE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pkey_ecd_digestverify(EVP_MD_CTX *ctx, const unsigned char *sig,
|
||||
size_t siglen, const unsigned char *tbs,
|
||||
size_t tbslen)
|
||||
{
|
||||
const X25519_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ptr;
|
||||
|
||||
if (siglen != ED25519_SIGSIZE)
|
||||
return 0;
|
||||
|
||||
return ED25519_verify(tbs, tbslen, sig, edkey->pubkey);
|
||||
}
|
||||
|
||||
static int pkey_ecd_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
{
|
||||
switch (type) {
|
||||
case EVP_PKEY_CTRL_MD:
|
||||
/* Only NULL allowed as digest */
|
||||
if (p2 == NULL)
|
||||
return 1;
|
||||
ECerr(EC_F_PKEY_ECD_CTRL, EC_R_INVALID_DIGEST_TYPE);
|
||||
return 0;
|
||||
|
||||
case EVP_PKEY_CTRL_DIGESTINIT:
|
||||
return 1;
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
|
||||
const EVP_PKEY_METHOD ed25519_pkey_meth = {
|
||||
EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
|
||||
0, 0, 0, 0, 0, 0,
|
||||
pkey_ecx_keygen,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
pkey_ecd_ctrl,
|
||||
0,
|
||||
pkey_ecd_digestsign,
|
||||
pkey_ecd_digestverify
|
||||
};
|
||||
Reference in New Issue
Block a user