mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
Upgrade openssl from 1.1.0e to 1.1.1b, with source code. 4.0.78
This commit is contained in:
parent
8f1c992379
commit
96dbd7bced
1476 changed files with 616554 additions and 4 deletions
1865
trunk/3rdparty/openssl-1.1-fit/crypto/ec/asm/ecp_nistz256-armv4.pl
vendored
Executable file
1865
trunk/3rdparty/openssl-1.1-fit/crypto/ec/asm/ecp_nistz256-armv4.pl
vendored
Executable file
File diff suppressed because it is too large
Load diff
1883
trunk/3rdparty/openssl-1.1-fit/crypto/ec/asm/ecp_nistz256-armv8.pl
vendored
Normal file
1883
trunk/3rdparty/openssl-1.1-fit/crypto/ec/asm/ecp_nistz256-armv8.pl
vendored
Normal file
File diff suppressed because it is too large
Load diff
2080
trunk/3rdparty/openssl-1.1-fit/crypto/ec/asm/ecp_nistz256-avx2.pl
vendored
Executable file
2080
trunk/3rdparty/openssl-1.1-fit/crypto/ec/asm/ecp_nistz256-avx2.pl
vendored
Executable file
File diff suppressed because it is too large
Load diff
2382
trunk/3rdparty/openssl-1.1-fit/crypto/ec/asm/ecp_nistz256-ppc64.pl
vendored
Executable file
2382
trunk/3rdparty/openssl-1.1-fit/crypto/ec/asm/ecp_nistz256-ppc64.pl
vendored
Executable file
File diff suppressed because it is too large
Load diff
3061
trunk/3rdparty/openssl-1.1-fit/crypto/ec/asm/ecp_nistz256-sparcv9.pl
vendored
Executable file
3061
trunk/3rdparty/openssl-1.1-fit/crypto/ec/asm/ecp_nistz256-sparcv9.pl
vendored
Executable file
File diff suppressed because it is too large
Load diff
1866
trunk/3rdparty/openssl-1.1-fit/crypto/ec/asm/ecp_nistz256-x86.pl
vendored
Executable file
1866
trunk/3rdparty/openssl-1.1-fit/crypto/ec/asm/ecp_nistz256-x86.pl
vendored
Executable file
File diff suppressed because it is too large
Load diff
4741
trunk/3rdparty/openssl-1.1-fit/crypto/ec/asm/ecp_nistz256-x86_64.pl
vendored
Executable file
4741
trunk/3rdparty/openssl-1.1-fit/crypto/ec/asm/ecp_nistz256-x86_64.pl
vendored
Executable file
File diff suppressed because it is too large
Load diff
824
trunk/3rdparty/openssl-1.1-fit/crypto/ec/asm/x25519-ppc64.pl
vendored
Executable file
824
trunk/3rdparty/openssl-1.1-fit/crypto/ec/asm/x25519-ppc64.pl
vendored
Executable file
|
@ -0,0 +1,824 @@
|
|||
#! /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 PPC64.
|
||||
#
|
||||
# July 2018.
|
||||
#
|
||||
# Base 2^64 is faster than base 2^51 on pre-POWER8, most notably ~15%
|
||||
# faster on PPC970/G5. POWER8 on the other hand seems to trip on own
|
||||
# shoelaces when handling longer carry chains. As base 2^51 has just
|
||||
# single-carry pairs, it's 25% faster than base 2^64. Since PPC970 is
|
||||
# pretty old, base 2^64 implementation is not engaged. Comparison to
|
||||
# compiler-generated code is complicated by the fact that not all
|
||||
# compilers support 128-bit integers. When compiler doesn't, like xlc,
|
||||
# this module delivers more than 2x improvement, and when it does,
|
||||
# from 12% to 30% improvement was measured...
|
||||
|
||||
$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) = map("r$_",3..5);
|
||||
|
||||
####################################################### base 2^64
|
||||
if (0) {
|
||||
my ($bi,$a0,$a1,$a2,$a3,$t0,$t1, $t2,$t3,
|
||||
$acc0,$acc1,$acc2,$acc3,$acc4,$acc5,$acc6,$acc7) =
|
||||
map("r$_",(6..12,22..31));
|
||||
my $zero = "r0";
|
||||
my $FRAME = 16*8;
|
||||
|
||||
$code.=<<___;
|
||||
.text
|
||||
|
||||
.globl x25519_fe64_mul
|
||||
.type x25519_fe64_mul,\@function
|
||||
.align 5
|
||||
x25519_fe64_mul:
|
||||
stdu $sp,-$FRAME($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)
|
||||
|
||||
ld $bi,0($bp)
|
||||
ld $a0,0($ap)
|
||||
xor $zero,$zero,$zero
|
||||
ld $a1,8($ap)
|
||||
ld $a2,16($ap)
|
||||
ld $a3,24($ap)
|
||||
|
||||
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
|
||||
___
|
||||
for(my @acc=($acc0,$acc1,$acc2,$acc3,$acc4,$acc5,$acc6,$acc7),
|
||||
my $i=1; $i<4; shift(@acc), $i++) {
|
||||
my $acc4 = $i==1? $zero : @acc[4];
|
||||
|
||||
$code.=<<___;
|
||||
ld $bi,`8*$i`($bp)
|
||||
addc @acc[1],@acc[1],$t0 # accumulate high parts
|
||||
mulld $t0,$a0,$bi
|
||||
adde @acc[2],@acc[2],$t1
|
||||
mulld $t1,$a1,$bi
|
||||
adde @acc[3],@acc[3],$t2
|
||||
mulld $t2,$a2,$bi
|
||||
adde @acc[4],$acc4,$t3
|
||||
mulld $t3,$a3,$bi
|
||||
addc @acc[1],@acc[1],$t0 # accumulate low parts
|
||||
mulhdu $t0,$a0,$bi
|
||||
adde @acc[2],@acc[2],$t1
|
||||
mulhdu $t1,$a1,$bi
|
||||
adde @acc[3],@acc[3],$t2
|
||||
mulhdu $t2,$a2,$bi
|
||||
adde @acc[4],@acc[4],$t3
|
||||
mulhdu $t3,$a3,$bi
|
||||
adde @acc[5],$zero,$zero
|
||||
___
|
||||
}
|
||||
$code.=<<___;
|
||||
li $bi,38
|
||||
addc $acc4,$acc4,$t0
|
||||
mulld $t0,$acc4,$bi
|
||||
adde $acc5,$acc5,$t1
|
||||
mulld $t1,$acc5,$bi
|
||||
adde $acc6,$acc6,$t2
|
||||
mulld $t2,$acc6,$bi
|
||||
adde $acc7,$acc7,$t3
|
||||
mulld $t3,$acc7,$bi
|
||||
|
||||
addc $acc0,$acc0,$t0
|
||||
mulhdu $t0,$acc4,$bi
|
||||
adde $acc1,$acc1,$t1
|
||||
mulhdu $t1,$acc5,$bi
|
||||
adde $acc2,$acc2,$t2
|
||||
mulhdu $t2,$acc6,$bi
|
||||
adde $acc3,$acc3,$t3
|
||||
mulhdu $t3,$acc7,$bi
|
||||
adde $acc4,$zero,$zero
|
||||
|
||||
addc $acc1,$acc1,$t0
|
||||
adde $acc2,$acc2,$t1
|
||||
adde $acc3,$acc3,$t2
|
||||
adde $acc4,$acc4,$t3
|
||||
|
||||
mulld $acc4,$acc4,$bi
|
||||
|
||||
addc $acc0,$acc0,$acc4
|
||||
addze $acc1,$acc1
|
||||
addze $acc2,$acc2
|
||||
addze $acc3,$acc3
|
||||
|
||||
subfe $acc4,$acc4,$acc4 # carry -> ~mask
|
||||
std $acc1,8($rp)
|
||||
andc $acc4,$bi,$acc4
|
||||
std $acc2,16($rp)
|
||||
add $acc0,$acc0,$acc4
|
||||
std $acc3,24($rp)
|
||||
std $acc0,0($rp)
|
||||
|
||||
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,10,3,0
|
||||
.long 0
|
||||
.size x25519_fe64_mul,.-x25519_fe64_mul
|
||||
|
||||
.globl x25519_fe64_sqr
|
||||
.type x25519_fe64_sqr,\@function
|
||||
.align 5
|
||||
x25519_fe64_sqr:
|
||||
stdu $sp,-$FRAME($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)
|
||||
|
||||
ld $a0,0($ap)
|
||||
xor $zero,$zero,$zero
|
||||
ld $a1,8($ap)
|
||||
ld $a2,16($ap)
|
||||
ld $a3,24($ap)
|
||||
|
||||
################################
|
||||
# | | | | | |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,$zero
|
||||
|
||||
addc $acc1,$acc1,$a0 # +a[i]*a[i]
|
||||
li $bi,38
|
||||
adde $acc2,$acc2,$t1
|
||||
adde $acc3,$acc3,$a1
|
||||
adde $acc4,$acc4,$t2
|
||||
adde $acc5,$acc5,$a2
|
||||
adde $acc6,$acc6,$t3
|
||||
adde $acc7,$acc7,$a3
|
||||
|
||||
mulld $t0,$acc4,$bi
|
||||
mulld $t1,$acc5,$bi
|
||||
mulld $t2,$acc6,$bi
|
||||
mulld $t3,$acc7,$bi
|
||||
|
||||
addc $acc0,$acc0,$t0
|
||||
mulhdu $t0,$acc4,$bi
|
||||
adde $acc1,$acc1,$t1
|
||||
mulhdu $t1,$acc5,$bi
|
||||
adde $acc2,$acc2,$t2
|
||||
mulhdu $t2,$acc6,$bi
|
||||
adde $acc3,$acc3,$t3
|
||||
mulhdu $t3,$acc7,$bi
|
||||
addze $acc4,$zero
|
||||
|
||||
addc $acc1,$acc1,$t0
|
||||
adde $acc2,$acc2,$t1
|
||||
adde $acc3,$acc3,$t2
|
||||
adde $acc4,$acc4,$t3
|
||||
|
||||
mulld $acc4,$acc4,$bi
|
||||
|
||||
addc $acc0,$acc0,$acc4
|
||||
addze $acc1,$acc1
|
||||
addze $acc2,$acc2
|
||||
addze $acc3,$acc3
|
||||
|
||||
subfe $acc4,$acc4,$acc4 # carry -> ~mask
|
||||
std $acc1,8($rp)
|
||||
andc $acc4,$bi,$acc4
|
||||
std $acc2,16($rp)
|
||||
add $acc0,$acc0,$acc4
|
||||
std $acc3,24($rp)
|
||||
std $acc0,0($rp)
|
||||
|
||||
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,10,2,0
|
||||
.long 0
|
||||
.size x25519_fe64_sqr,.-x25519_fe64_sqr
|
||||
|
||||
.globl x25519_fe64_mul121666
|
||||
.type x25519_fe64_mul121666,\@function
|
||||
.align 5
|
||||
x25519_fe64_mul121666:
|
||||
lis $bi,`65536>>16`
|
||||
ori $bi,$bi,`121666-65536`
|
||||
|
||||
ld $t0,0($ap)
|
||||
ld $t1,8($ap)
|
||||
ld $bp,16($ap)
|
||||
ld $ap,24($ap)
|
||||
|
||||
mulld $a0,$t0,$bi
|
||||
mulhdu $t0,$t0,$bi
|
||||
mulld $a1,$t1,$bi
|
||||
mulhdu $t1,$t1,$bi
|
||||
mulld $a2,$bp,$bi
|
||||
mulhdu $bp,$bp,$bi
|
||||
mulld $a3,$ap,$bi
|
||||
mulhdu $ap,$ap,$bi
|
||||
|
||||
addc $a1,$a1,$t0
|
||||
adde $a2,$a2,$t1
|
||||
adde $a3,$a3,$bp
|
||||
addze $ap, $ap
|
||||
|
||||
mulli $ap,$ap,38
|
||||
|
||||
addc $a0,$a0,$ap
|
||||
addze $a1,$a1
|
||||
addze $a2,$a2
|
||||
addze $a3,$a3
|
||||
|
||||
subfe $t1,$t1,$t1 # carry -> ~mask
|
||||
std $a1,8($rp)
|
||||
andc $t0,$t0,$t1
|
||||
std $a2,16($rp)
|
||||
add $a0,$a0,$t0
|
||||
std $a3,24($rp)
|
||||
std $a0,0($rp)
|
||||
|
||||
blr
|
||||
.long 0
|
||||
.byte 0,12,0x14,0,0,0,2,0
|
||||
.long 0
|
||||
.size x25519_fe64_mul121666,.-x25519_fe64_mul121666
|
||||
|
||||
.globl x25519_fe64_add
|
||||
.type x25519_fe64_add,\@function
|
||||
.align 5
|
||||
x25519_fe64_add:
|
||||
ld $a0,0($ap)
|
||||
ld $t0,0($bp)
|
||||
ld $a1,8($ap)
|
||||
ld $t1,8($bp)
|
||||
ld $a2,16($ap)
|
||||
ld $bi,16($bp)
|
||||
ld $a3,24($ap)
|
||||
ld $bp,24($bp)
|
||||
|
||||
addc $a0,$a0,$t0
|
||||
adde $a1,$a1,$t1
|
||||
adde $a2,$a2,$bi
|
||||
adde $a3,$a3,$bp
|
||||
|
||||
li $t0,38
|
||||
subfe $t1,$t1,$t1 # carry -> ~mask
|
||||
andc $t1,$t0,$t1
|
||||
|
||||
addc $a0,$a0,$t1
|
||||
addze $a1,$a1
|
||||
addze $a2,$a2
|
||||
addze $a3,$a3
|
||||
|
||||
subfe $t1,$t1,$t1 # carry -> ~mask
|
||||
std $a1,8($rp)
|
||||
andc $t0,$t0,$t1
|
||||
std $a2,16($rp)
|
||||
add $a0,$a0,$t0
|
||||
std $a3,24($rp)
|
||||
std $a0,0($rp)
|
||||
|
||||
blr
|
||||
.long 0
|
||||
.byte 0,12,0x14,0,0,0,3,0
|
||||
.long 0
|
||||
.size x25519_fe64_add,.-x25519_fe64_add
|
||||
|
||||
.globl x25519_fe64_sub
|
||||
.type x25519_fe64_sub,\@function
|
||||
.align 5
|
||||
x25519_fe64_sub:
|
||||
ld $a0,0($ap)
|
||||
ld $t0,0($bp)
|
||||
ld $a1,8($ap)
|
||||
ld $t1,8($bp)
|
||||
ld $a2,16($ap)
|
||||
ld $bi,16($bp)
|
||||
ld $a3,24($ap)
|
||||
ld $bp,24($bp)
|
||||
|
||||
subfc $a0,$t0,$a0
|
||||
subfe $a1,$t1,$a1
|
||||
subfe $a2,$bi,$a2
|
||||
subfe $a3,$bp,$a3
|
||||
|
||||
li $t0,38
|
||||
subfe $t1,$t1,$t1 # borrow -> mask
|
||||
xor $zero,$zero,$zero
|
||||
and $t1,$t0,$t1
|
||||
|
||||
subfc $a0,$t1,$a0
|
||||
subfe $a1,$zero,$a1
|
||||
subfe $a2,$zero,$a2
|
||||
subfe $a3,$zero,$a3
|
||||
|
||||
subfe $t1,$t1,$t1 # borrow -> mask
|
||||
std $a1,8($rp)
|
||||
and $t0,$t0,$t1
|
||||
std $a2,16($rp)
|
||||
subf $a0,$t0,$a0
|
||||
std $a3,24($rp)
|
||||
std $a0,0($rp)
|
||||
|
||||
blr
|
||||
.long 0
|
||||
.byte 0,12,0x14,0,0,0,3,0
|
||||
.long 0
|
||||
.size x25519_fe64_sub,.-x25519_fe64_sub
|
||||
|
||||
.globl x25519_fe64_tobytes
|
||||
.type x25519_fe64_tobytes,\@function
|
||||
.align 5
|
||||
x25519_fe64_tobytes:
|
||||
ld $a3,24($ap)
|
||||
ld $a0,0($ap)
|
||||
ld $a1,8($ap)
|
||||
ld $a2,16($ap)
|
||||
|
||||
sradi $t0,$a3,63 # most significant bit -> mask
|
||||
li $t1,19
|
||||
and $t0,$t0,$t1
|
||||
sldi $a3,$a3,1
|
||||
add $t0,$t0,$t1 # compare to modulus in the same go
|
||||
srdi $a3,$a3,1 # most signifcant bit cleared
|
||||
|
||||
addc $a0,$a0,$t0
|
||||
addze $a1,$a1
|
||||
addze $a2,$a2
|
||||
addze $a3,$a3
|
||||
|
||||
xor $zero,$zero,$zero
|
||||
sradi $t0,$a3,63 # most significant bit -> mask
|
||||
sldi $a3,$a3,1
|
||||
andc $t0,$t1,$t0
|
||||
srdi $a3,$a3,1 # most signifcant bit cleared
|
||||
|
||||
subi $rp,$rp,1
|
||||
subfc $a0,$t0,$a0
|
||||
subfe $a1,$zero,$a1
|
||||
subfe $a2,$zero,$a2
|
||||
subfe $a3,$zero,$a3
|
||||
|
||||
___
|
||||
for (my @a=($a0,$a1,$a2,$a3), my $i=0; $i<4; shift(@a), $i++) {
|
||||
$code.=<<___;
|
||||
srdi $t0,@a[0],8
|
||||
stbu @a[0],1($rp)
|
||||
srdi @a[0],@a[0],16
|
||||
stbu $t0,1($rp)
|
||||
srdi $t0,@a[0],8
|
||||
stbu @a[0],1($rp)
|
||||
srdi @a[0],@a[0],16
|
||||
stbu $t0,1($rp)
|
||||
srdi $t0,@a[0],8
|
||||
stbu @a[0],1($rp)
|
||||
srdi @a[0],@a[0],16
|
||||
stbu $t0,1($rp)
|
||||
srdi $t0,@a[0],8
|
||||
stbu @a[0],1($rp)
|
||||
stbu $t0,1($rp)
|
||||
___
|
||||
}
|
||||
$code.=<<___;
|
||||
blr
|
||||
.long 0
|
||||
.byte 0,12,0x14,0,0,0,2,0
|
||||
.long 0
|
||||
.size x25519_fe64_tobytes,.-x25519_fe64_tobytes
|
||||
___
|
||||
}
|
||||
####################################################### base 2^51
|
||||
{
|
||||
my ($bi,$a0,$a1,$a2,$a3,$a4,$t0, $t1,
|
||||
$h0lo,$h0hi,$h1lo,$h1hi,$h2lo,$h2hi,$h3lo,$h3hi,$h4lo,$h4hi) =
|
||||
map("r$_",(6..12,21..31));
|
||||
my $mask = "r0";
|
||||
my $FRAME = 18*8;
|
||||
|
||||
$code.=<<___;
|
||||
.text
|
||||
|
||||
.globl x25519_fe51_mul
|
||||
.type x25519_fe51_mul,\@function
|
||||
.align 5
|
||||
x25519_fe51_mul:
|
||||
stdu $sp,-$FRAME($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)
|
||||
|
||||
ld $bi,0($bp)
|
||||
ld $a0,0($ap)
|
||||
ld $a1,8($ap)
|
||||
ld $a2,16($ap)
|
||||
ld $a3,24($ap)
|
||||
ld $a4,32($ap)
|
||||
|
||||
mulld $h0lo,$a0,$bi # a[0]*b[0]
|
||||
mulhdu $h0hi,$a0,$bi
|
||||
|
||||
mulld $h1lo,$a1,$bi # a[1]*b[0]
|
||||
mulhdu $h1hi,$a1,$bi
|
||||
|
||||
mulld $h4lo,$a4,$bi # a[4]*b[0]
|
||||
mulhdu $h4hi,$a4,$bi
|
||||
ld $ap,8($bp)
|
||||
mulli $a4,$a4,19
|
||||
|
||||
mulld $h2lo,$a2,$bi # a[2]*b[0]
|
||||
mulhdu $h2hi,$a2,$bi
|
||||
|
||||
mulld $h3lo,$a3,$bi # a[3]*b[0]
|
||||
mulhdu $h3hi,$a3,$bi
|
||||
___
|
||||
for(my @a=($a0,$a1,$a2,$a3,$a4),
|
||||
my $i=1; $i<4; $i++) {
|
||||
($ap,$bi) = ($bi,$ap);
|
||||
$code.=<<___;
|
||||
mulld $t0,@a[4],$bi
|
||||
mulhdu $t1,@a[4],$bi
|
||||
addc $h0lo,$h0lo,$t0
|
||||
adde $h0hi,$h0hi,$t1
|
||||
|
||||
mulld $t0,@a[0],$bi
|
||||
mulhdu $t1,@a[0],$bi
|
||||
addc $h1lo,$h1lo,$t0
|
||||
adde $h1hi,$h1hi,$t1
|
||||
|
||||
mulld $t0,@a[3],$bi
|
||||
mulhdu $t1,@a[3],$bi
|
||||
ld $ap,`8*($i+1)`($bp)
|
||||
mulli @a[3],@a[3],19
|
||||
addc $h4lo,$h4lo,$t0
|
||||
adde $h4hi,$h4hi,$t1
|
||||
|
||||
mulld $t0,@a[1],$bi
|
||||
mulhdu $t1,@a[1],$bi
|
||||
addc $h2lo,$h2lo,$t0
|
||||
adde $h2hi,$h2hi,$t1
|
||||
|
||||
mulld $t0,@a[2],$bi
|
||||
mulhdu $t1,@a[2],$bi
|
||||
addc $h3lo,$h3lo,$t0
|
||||
adde $h3hi,$h3hi,$t1
|
||||
___
|
||||
unshift(@a,pop(@a));
|
||||
}
|
||||
($ap,$bi) = ($bi,$ap);
|
||||
$code.=<<___;
|
||||
mulld $t0,$a1,$bi
|
||||
mulhdu $t1,$a1,$bi
|
||||
addc $h0lo,$h0lo,$t0
|
||||
adde $h0hi,$h0hi,$t1
|
||||
|
||||
mulld $t0,$a2,$bi
|
||||
mulhdu $t1,$a2,$bi
|
||||
addc $h1lo,$h1lo,$t0
|
||||
adde $h1hi,$h1hi,$t1
|
||||
|
||||
mulld $t0,$a3,$bi
|
||||
mulhdu $t1,$a3,$bi
|
||||
addc $h2lo,$h2lo,$t0
|
||||
adde $h2hi,$h2hi,$t1
|
||||
|
||||
mulld $t0,$a4,$bi
|
||||
mulhdu $t1,$a4,$bi
|
||||
addc $h3lo,$h3lo,$t0
|
||||
adde $h3hi,$h3hi,$t1
|
||||
|
||||
mulld $t0,$a0,$bi
|
||||
mulhdu $t1,$a0,$bi
|
||||
addc $h4lo,$h4lo,$t0
|
||||
adde $h4hi,$h4hi,$t1
|
||||
|
||||
.Lfe51_reduce:
|
||||
li $mask,-1
|
||||
srdi $mask,$mask,13 # 0x7ffffffffffff
|
||||
|
||||
srdi $t0,$h2lo,51
|
||||
and $a2,$h2lo,$mask
|
||||
insrdi $t0,$h2hi,51,0 # h2>>51
|
||||
srdi $t1,$h0lo,51
|
||||
and $a0,$h0lo,$mask
|
||||
insrdi $t1,$h0hi,51,0 # h0>>51
|
||||
addc $h3lo,$h3lo,$t0
|
||||
addze $h3hi,$h3hi
|
||||
addc $h1lo,$h1lo,$t1
|
||||
addze $h1hi,$h1hi
|
||||
|
||||
srdi $t0,$h3lo,51
|
||||
and $a3,$h3lo,$mask
|
||||
insrdi $t0,$h3hi,51,0 # h3>>51
|
||||
srdi $t1,$h1lo,51
|
||||
and $a1,$h1lo,$mask
|
||||
insrdi $t1,$h1hi,51,0 # h1>>51
|
||||
addc $h4lo,$h4lo,$t0
|
||||
addze $h4hi,$h4hi
|
||||
add $a2,$a2,$t1
|
||||
|
||||
srdi $t0,$h4lo,51
|
||||
and $a4,$h4lo,$mask
|
||||
insrdi $t0,$h4hi,51,0
|
||||
mulli $t0,$t0,19 # (h4 >> 51) * 19
|
||||
|
||||
add $a0,$a0,$t0
|
||||
|
||||
srdi $t1,$a2,51
|
||||
and $a2,$a2,$mask
|
||||
add $a3,$a3,$t1
|
||||
|
||||
srdi $t0,$a0,51
|
||||
and $a0,$a0,$mask
|
||||
add $a1,$a1,$t0
|
||||
|
||||
std $a2,16($rp)
|
||||
std $a3,24($rp)
|
||||
std $a4,32($rp)
|
||||
std $a0,0($rp)
|
||||
std $a1,8($rp)
|
||||
|
||||
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,11,3,0
|
||||
.long 0
|
||||
.size x25519_fe51_mul,.-x25519_fe51_mul
|
||||
___
|
||||
{
|
||||
my ($a0,$a1,$a2,$a3,$a4,$t0,$t1) = ($a0,$a1,$a2,$a3,$a4,$t0,$t1);
|
||||
$code.=<<___;
|
||||
.globl x25519_fe51_sqr
|
||||
.type x25519_fe51_sqr,\@function
|
||||
.align 5
|
||||
x25519_fe51_sqr:
|
||||
stdu $sp,-$FRAME($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)
|
||||
|
||||
ld $a0,0($ap)
|
||||
ld $a1,8($ap)
|
||||
ld $a2,16($ap)
|
||||
ld $a3,24($ap)
|
||||
ld $a4,32($ap)
|
||||
|
||||
add $bi,$a0,$a0 # a[0]*2
|
||||
mulli $t1,$a4,19 # a[4]*19
|
||||
|
||||
mulld $h0lo,$a0,$a0
|
||||
mulhdu $h0hi,$a0,$a0
|
||||
mulld $h1lo,$a1,$bi
|
||||
mulhdu $h1hi,$a1,$bi
|
||||
mulld $h2lo,$a2,$bi
|
||||
mulhdu $h2hi,$a2,$bi
|
||||
mulld $h3lo,$a3,$bi
|
||||
mulhdu $h3hi,$a3,$bi
|
||||
mulld $h4lo,$a4,$bi
|
||||
mulhdu $h4hi,$a4,$bi
|
||||
add $bi,$a1,$a1 # a[1]*2
|
||||
___
|
||||
($a4,$t1) = ($t1,$a4);
|
||||
$code.=<<___;
|
||||
mulld $t0,$t1,$a4
|
||||
mulhdu $t1,$t1,$a4
|
||||
addc $h3lo,$h3lo,$t0
|
||||
adde $h3hi,$h3hi,$t1
|
||||
|
||||
mulli $bp,$a3,19 # a[3]*19
|
||||
|
||||
mulld $t0,$a1,$a1
|
||||
mulhdu $t1,$a1,$a1
|
||||
addc $h2lo,$h2lo,$t0
|
||||
adde $h2hi,$h2hi,$t1
|
||||
mulld $t0,$a2,$bi
|
||||
mulhdu $t1,$a2,$bi
|
||||
addc $h3lo,$h3lo,$t0
|
||||
adde $h3hi,$h3hi,$t1
|
||||
mulld $t0,$a3,$bi
|
||||
mulhdu $t1,$a3,$bi
|
||||
addc $h4lo,$h4lo,$t0
|
||||
adde $h4hi,$h4hi,$t1
|
||||
mulld $t0,$a4,$bi
|
||||
mulhdu $t1,$a4,$bi
|
||||
add $bi,$a3,$a3 # a[3]*2
|
||||
addc $h0lo,$h0lo,$t0
|
||||
adde $h0hi,$h0hi,$t1
|
||||
___
|
||||
($a3,$t1) = ($bp,$a3);
|
||||
$code.=<<___;
|
||||
mulld $t0,$t1,$a3
|
||||
mulhdu $t1,$t1,$a3
|
||||
addc $h1lo,$h1lo,$t0
|
||||
adde $h1hi,$h1hi,$t1
|
||||
mulld $t0,$bi,$a4
|
||||
mulhdu $t1,$bi,$a4
|
||||
add $bi,$a2,$a2 # a[2]*2
|
||||
addc $h2lo,$h2lo,$t0
|
||||
adde $h2hi,$h2hi,$t1
|
||||
|
||||
mulld $t0,$a2,$a2
|
||||
mulhdu $t1,$a2,$a2
|
||||
addc $h4lo,$h4lo,$t0
|
||||
adde $h4hi,$h4hi,$t1
|
||||
mulld $t0,$a3,$bi
|
||||
mulhdu $t1,$a3,$bi
|
||||
addc $h0lo,$h0lo,$t0
|
||||
adde $h0hi,$h0hi,$t1
|
||||
mulld $t0,$a4,$bi
|
||||
mulhdu $t1,$a4,$bi
|
||||
addc $h1lo,$h1lo,$t0
|
||||
adde $h1hi,$h1hi,$t1
|
||||
|
||||
b .Lfe51_reduce
|
||||
.long 0
|
||||
.byte 0,12,4,0,0x80,11,2,0
|
||||
.long 0
|
||||
.size x25519_fe51_sqr,.-x25519_fe51_sqr
|
||||
___
|
||||
}
|
||||
$code.=<<___;
|
||||
.globl x25519_fe51_mul121666
|
||||
.type x25519_fe51_mul121666,\@function
|
||||
.align 5
|
||||
x25519_fe51_mul121666:
|
||||
stdu $sp,-$FRAME($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)
|
||||
|
||||
lis $bi,`65536>>16`
|
||||
ori $bi,$bi,`121666-65536`
|
||||
ld $a0,0($ap)
|
||||
ld $a1,8($ap)
|
||||
ld $a2,16($ap)
|
||||
ld $a3,24($ap)
|
||||
ld $a4,32($ap)
|
||||
|
||||
mulld $h0lo,$a0,$bi # a[0]*121666
|
||||
mulhdu $h0hi,$a0,$bi
|
||||
mulld $h1lo,$a1,$bi # a[1]*121666
|
||||
mulhdu $h1hi,$a1,$bi
|
||||
mulld $h2lo,$a2,$bi # a[2]*121666
|
||||
mulhdu $h2hi,$a2,$bi
|
||||
mulld $h3lo,$a3,$bi # a[3]*121666
|
||||
mulhdu $h3hi,$a3,$bi
|
||||
mulld $h4lo,$a4,$bi # a[4]*121666
|
||||
mulhdu $h4hi,$a4,$bi
|
||||
|
||||
b .Lfe51_reduce
|
||||
.long 0
|
||||
.byte 0,12,4,0,0x80,11,2,0
|
||||
.long 0
|
||||
.size x25519_fe51_mul121666,.-x25519_fe51_mul121666
|
||||
___
|
||||
}
|
||||
|
||||
$code =~ s/\`([^\`]*)\`/eval $1/gem;
|
||||
print $code;
|
||||
close STDOUT;
|
1117
trunk/3rdparty/openssl-1.1-fit/crypto/ec/asm/x25519-x86_64.pl
vendored
Executable file
1117
trunk/3rdparty/openssl-1.1-fit/crypto/ec/asm/x25519-x86_64.pl
vendored
Executable file
File diff suppressed because it is too large
Load diff
42
trunk/3rdparty/openssl-1.1-fit/crypto/ec/build.info
vendored
Normal file
42
trunk/3rdparty/openssl-1.1-fit/crypto/ec/build.info
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
LIBS=../../libcrypto
|
||||
SOURCE[../../libcrypto]=\
|
||||
ec_lib.c ecp_smpl.c ecp_mont.c ecp_nist.c ec_cvt.c ec_mult.c \
|
||||
ec_err.c ec_curve.c ec_check.c ec_print.c ec_asn1.c ec_key.c \
|
||||
ec2_smpl.c ec_ameth.c ec_pmeth.c eck_prn.c \
|
||||
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) $(LIB_CFLAGS) $(LIB_CPPFLAGS) $(PROCESSOR)
|
||||
|
||||
GENERATE[ecp_nistz256-x86_64.s]=asm/ecp_nistz256-x86_64.pl $(PERLASM_SCHEME)
|
||||
|
||||
GENERATE[ecp_nistz256-avx2.s]=asm/ecp_nistz256-avx2.pl $(PERLASM_SCHEME)
|
||||
|
||||
GENERATE[ecp_nistz256-sparcv9.S]=asm/ecp_nistz256-sparcv9.pl $(PERLASM_SCHEME)
|
||||
INCLUDE[ecp_nistz256-sparcv9.o]=..
|
||||
|
||||
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)
|
||||
GENERATE[x25519-ppc64.s]=asm/x25519-ppc64.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
|
5596
trunk/3rdparty/openssl-1.1-fit/crypto/ec/curve25519.c
vendored
Normal file
5596
trunk/3rdparty/openssl-1.1-fit/crypto/ec/curve25519.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
27
trunk/3rdparty/openssl-1.1-fit/crypto/ec/curve448/arch_32/arch_intrinsics.h
vendored
Normal file
27
trunk/3rdparty/openssl-1.1-fit/crypto/ec/curve448/arch_32/arch_intrinsics.h
vendored
Normal file
|
@ -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 */
|
95
trunk/3rdparty/openssl-1.1-fit/crypto/ec/curve448/arch_32/f_impl.c
vendored
Normal file
95
trunk/3rdparty/openssl-1.1-fit/crypto/ec/curve448/arch_32/f_impl.c
vendored
Normal file
|
@ -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 */
|
||||
}
|
60
trunk/3rdparty/openssl-1.1-fit/crypto/ec/curve448/arch_32/f_impl.h
vendored
Normal file
60
trunk/3rdparty/openssl-1.1-fit/crypto/ec/curve448/arch_32/f_impl.h
vendored
Normal file
|
@ -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 */
|
727
trunk/3rdparty/openssl-1.1-fit/crypto/ec/curve448/curve448.c
vendored
Normal file
727
trunk/3rdparty/openssl-1.1-fit/crypto/ec/curve448/curve448.c
vendored
Normal file
|
@ -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 * (1 << 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);
|
||||
}
|
38
trunk/3rdparty/openssl-1.1-fit/crypto/ec/curve448/curve448_lcl.h
vendored
Normal file
38
trunk/3rdparty/openssl-1.1-fit/crypto/ec/curve448/curve448_lcl.h
vendored
Normal file
|
@ -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 */
|
475
trunk/3rdparty/openssl-1.1-fit/crypto/ec/curve448/curve448_tables.c
vendored
Normal file
475
trunk/3rdparty/openssl-1.1-fit/crypto/ec/curve448/curve448_tables.c
vendored
Normal file
|
@ -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;
|
78
trunk/3rdparty/openssl-1.1-fit/crypto/ec/curve448/curve448utils.h
vendored
Normal file
78
trunk/3rdparty/openssl-1.1-fit/crypto/ec/curve448/curve448utils.h
vendored
Normal file
|
@ -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__ */
|
195
trunk/3rdparty/openssl-1.1-fit/crypto/ec/curve448/ed448.h
vendored
Normal file
195
trunk/3rdparty/openssl-1.1-fit/crypto/ec/curve448/ed448.h
vendored
Normal file
|
@ -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 */
|
372
trunk/3rdparty/openssl-1.1-fit/crypto/ec/curve448/eddsa.c
vendored
Normal file
372
trunk/3rdparty/openssl-1.1-fit/crypto/ec/curve448/eddsa.c
vendored
Normal file
|
@ -0,0 +1,372 @@
|
|||
/*
|
||||
* 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))
|
||||
|| !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)
|
||||
|| !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)
|
||||
|| !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_scalar_t challenge_scalar;
|
||||
curve448_scalar_t response_scalar;
|
||||
/* Order in little endian format */
|
||||
static const uint8_t order[] = {
|
||||
0xF3, 0x44, 0x58, 0xAB, 0x92, 0xC2, 0x78, 0x23, 0x55, 0x8F, 0xC5, 0x8D,
|
||||
0x72, 0xC2, 0x6C, 0x21, 0x90, 0x36, 0xD6, 0xAE, 0x49, 0xDB, 0x4E, 0xC4,
|
||||
0xE9, 0x23, 0xCA, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00
|
||||
};
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Check that s (second 57 bytes of the sig) is less than the order. Both
|
||||
* s and the order are in little-endian format. This can be done in
|
||||
* variable time, since if this is not the case the signature if publicly
|
||||
* invalid.
|
||||
*/
|
||||
for (i = EDDSA_448_PUBLIC_BYTES - 1; i >= 0; i--) {
|
||||
if (signature[i + EDDSA_448_PUBLIC_BYTES] > order[i])
|
||||
return C448_FAILURE;
|
||||
if (signature[i + EDDSA_448_PUBLIC_BYTES] < order[i])
|
||||
break;
|
||||
}
|
||||
if (i < 0)
|
||||
return C448_FAILURE;
|
||||
|
||||
error =
|
||||
curve448_point_decode_like_eddsa_and_mul_by_ratio(pk_point, pubkey);
|
||||
|
||||
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);
|
||||
|
||||
/* 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;
|
||||
}
|
204
trunk/3rdparty/openssl-1.1-fit/crypto/ec/curve448/f_generic.c
vendored
Normal file
204
trunk/3rdparty/openssl-1.1-fit/crypto/ec/curve448/f_generic.c
vendored
Normal file
|
@ -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(scarry == 0 || 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(carry < 2 && ((word_t)carry + scarry_0) == 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);
|
||||
}
|
168
trunk/3rdparty/openssl-1.1-fit/crypto/ec/curve448/field.h
vendored
Normal file
168
trunk/3rdparty/openssl-1.1-fit/crypto/ec/curve448/field.h
vendored
Normal file
|
@ -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__(16)))
|
||||
# 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 */
|
301
trunk/3rdparty/openssl-1.1-fit/crypto/ec/curve448/point_448.h
vendored
Normal file
301
trunk/3rdparty/openssl-1.1-fit/crypto/ec/curve448/point_448.h
vendored
Normal file
|
@ -0,0 +1,301 @@
|
|||
/*
|
||||
* Copyright 2017-2019 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 */
|
235
trunk/3rdparty/openssl-1.1-fit/crypto/ec/curve448/scalar.c
vendored
Normal file
235
trunk/3rdparty/openssl-1.1-fit/crypto/ec/curve448/scalar.c
vendored
Normal file
|
@ -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,
|
||||
size_t nbytes)
|
||||
{
|
||||
size_t 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));
|
||||
}
|
81
trunk/3rdparty/openssl-1.1-fit/crypto/ec/curve448/word.h
vendored
Normal file
81
trunk/3rdparty/openssl-1.1-fit/crypto/ec/curve448/word.h
vendored
Normal file
|
@ -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 */
|
337
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ec2_oct.c
vendored
Normal file
337
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ec2_oct.c
vendored
Normal file
|
@ -0,0 +1,337 @@
|
|||
/*
|
||||
* Copyright 2011-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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "ec_lcl.h"
|
||||
|
||||
#ifndef OPENSSL_NO_EC2M
|
||||
|
||||
/*-
|
||||
* Calculates and sets the affine coordinates of an EC_POINT from the given
|
||||
* compressed coordinates. Uses algorithm 2.3.4 of SEC 1.
|
||||
* Note that the simple implementation only uses affine coordinates.
|
||||
*
|
||||
* The method is from the following publication:
|
||||
*
|
||||
* Harper, Menezes, Vanstone:
|
||||
* "Public-Key Cryptosystems with Very Small Key Lengths",
|
||||
* EUROCRYPT '92, Springer-Verlag LNCS 658,
|
||||
* published February 1993
|
||||
*
|
||||
* US Patents 6,141,420 and 6,618,483 (Vanstone, Mullin, Agnew) describe
|
||||
* the same method, but claim no priority date earlier than July 29, 1994
|
||||
* (and additionally fail to cite the EUROCRYPT '92 publication as prior art).
|
||||
*/
|
||||
int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group,
|
||||
EC_POINT *point,
|
||||
const BIGNUM *x_, int y_bit,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
BN_CTX *new_ctx = NULL;
|
||||
BIGNUM *tmp, *x, *y, *z;
|
||||
int ret = 0, z0;
|
||||
|
||||
/* clear error queue */
|
||||
ERR_clear_error();
|
||||
|
||||
if (ctx == NULL) {
|
||||
ctx = new_ctx = BN_CTX_new();
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
}
|
||||
|
||||
y_bit = (y_bit != 0) ? 1 : 0;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
tmp = BN_CTX_get(ctx);
|
||||
x = BN_CTX_get(ctx);
|
||||
y = BN_CTX_get(ctx);
|
||||
z = BN_CTX_get(ctx);
|
||||
if (z == NULL)
|
||||
goto err;
|
||||
|
||||
if (!BN_GF2m_mod_arr(x, x_, group->poly))
|
||||
goto err;
|
||||
if (BN_is_zero(x)) {
|
||||
if (!BN_GF2m_mod_sqrt_arr(y, group->b, group->poly, ctx))
|
||||
goto err;
|
||||
} else {
|
||||
if (!group->meth->field_sqr(group, tmp, x, ctx))
|
||||
goto err;
|
||||
if (!group->meth->field_div(group, tmp, group->b, tmp, ctx))
|
||||
goto err;
|
||||
if (!BN_GF2m_add(tmp, group->a, tmp))
|
||||
goto err;
|
||||
if (!BN_GF2m_add(tmp, x, tmp))
|
||||
goto err;
|
||||
if (!BN_GF2m_mod_solve_quad_arr(z, tmp, group->poly, ctx)) {
|
||||
unsigned long err = ERR_peek_last_error();
|
||||
|
||||
if (ERR_GET_LIB(err) == ERR_LIB_BN
|
||||
&& ERR_GET_REASON(err) == BN_R_NO_SOLUTION) {
|
||||
ERR_clear_error();
|
||||
ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES,
|
||||
EC_R_INVALID_COMPRESSED_POINT);
|
||||
} else
|
||||
ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES,
|
||||
ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
z0 = (BN_is_odd(z)) ? 1 : 0;
|
||||
if (!group->meth->field_mul(group, y, x, z, ctx))
|
||||
goto err;
|
||||
if (z0 != y_bit) {
|
||||
if (!BN_GF2m_add(y, y, x))
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (!EC_POINT_set_affine_coordinates(group, point, x, y, ctx))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Converts an EC_POINT to an octet string. If buf is NULL, the encoded
|
||||
* length will be returned. If the length len of buf is smaller than required
|
||||
* an error will be returned.
|
||||
*/
|
||||
size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point,
|
||||
point_conversion_form_t form,
|
||||
unsigned char *buf, size_t len, BN_CTX *ctx)
|
||||
{
|
||||
size_t ret;
|
||||
BN_CTX *new_ctx = NULL;
|
||||
int used_ctx = 0;
|
||||
BIGNUM *x, *y, *yxi;
|
||||
size_t field_len, i, skip;
|
||||
|
||||
if ((form != POINT_CONVERSION_COMPRESSED)
|
||||
&& (form != POINT_CONVERSION_UNCOMPRESSED)
|
||||
&& (form != POINT_CONVERSION_HYBRID)) {
|
||||
ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_INVALID_FORM);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (EC_POINT_is_at_infinity(group, point)) {
|
||||
/* encodes to a single 0 octet */
|
||||
if (buf != NULL) {
|
||||
if (len < 1) {
|
||||
ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
buf[0] = 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ret := required output buffer length */
|
||||
field_len = (EC_GROUP_get_degree(group) + 7) / 8;
|
||||
ret =
|
||||
(form ==
|
||||
POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len;
|
||||
|
||||
/* if 'buf' is NULL, just return required length */
|
||||
if (buf != NULL) {
|
||||
if (len < ret) {
|
||||
ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (ctx == NULL) {
|
||||
ctx = new_ctx = BN_CTX_new();
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
}
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
used_ctx = 1;
|
||||
x = BN_CTX_get(ctx);
|
||||
y = BN_CTX_get(ctx);
|
||||
yxi = BN_CTX_get(ctx);
|
||||
if (yxi == NULL)
|
||||
goto err;
|
||||
|
||||
if (!EC_POINT_get_affine_coordinates(group, point, x, y, ctx))
|
||||
goto err;
|
||||
|
||||
buf[0] = form;
|
||||
if ((form != POINT_CONVERSION_UNCOMPRESSED) && !BN_is_zero(x)) {
|
||||
if (!group->meth->field_div(group, yxi, y, x, ctx))
|
||||
goto err;
|
||||
if (BN_is_odd(yxi))
|
||||
buf[0]++;
|
||||
}
|
||||
|
||||
i = 1;
|
||||
|
||||
skip = field_len - BN_num_bytes(x);
|
||||
if (skip > field_len) {
|
||||
ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
while (skip > 0) {
|
||||
buf[i++] = 0;
|
||||
skip--;
|
||||
}
|
||||
skip = BN_bn2bin(x, buf + i);
|
||||
i += skip;
|
||||
if (i != 1 + field_len) {
|
||||
ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (form == POINT_CONVERSION_UNCOMPRESSED
|
||||
|| form == POINT_CONVERSION_HYBRID) {
|
||||
skip = field_len - BN_num_bytes(y);
|
||||
if (skip > field_len) {
|
||||
ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
while (skip > 0) {
|
||||
buf[i++] = 0;
|
||||
skip--;
|
||||
}
|
||||
skip = BN_bn2bin(y, buf + i);
|
||||
i += skip;
|
||||
}
|
||||
|
||||
if (i != ret) {
|
||||
ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (used_ctx)
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
|
||||
err:
|
||||
if (used_ctx)
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Converts an octet string representation to an EC_POINT. Note that the
|
||||
* simple implementation only uses affine coordinates.
|
||||
*/
|
||||
int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
|
||||
const unsigned char *buf, size_t len,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
point_conversion_form_t form;
|
||||
int y_bit;
|
||||
BN_CTX *new_ctx = NULL;
|
||||
BIGNUM *x, *y, *yxi;
|
||||
size_t field_len, enc_len;
|
||||
int ret = 0;
|
||||
|
||||
if (len == 0) {
|
||||
ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
form = buf[0];
|
||||
y_bit = form & 1;
|
||||
form = form & ~1U;
|
||||
if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED)
|
||||
&& (form != POINT_CONVERSION_UNCOMPRESSED)
|
||||
&& (form != POINT_CONVERSION_HYBRID)) {
|
||||
ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
|
||||
return 0;
|
||||
}
|
||||
if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) {
|
||||
ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (form == 0) {
|
||||
if (len != 1) {
|
||||
ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return EC_POINT_set_to_infinity(group, point);
|
||||
}
|
||||
|
||||
field_len = (EC_GROUP_get_degree(group) + 7) / 8;
|
||||
enc_len =
|
||||
(form ==
|
||||
POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len;
|
||||
|
||||
if (len != enc_len) {
|
||||
ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ctx == NULL) {
|
||||
ctx = new_ctx = BN_CTX_new();
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
}
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
x = BN_CTX_get(ctx);
|
||||
y = BN_CTX_get(ctx);
|
||||
yxi = BN_CTX_get(ctx);
|
||||
if (yxi == NULL)
|
||||
goto err;
|
||||
|
||||
if (!BN_bin2bn(buf + 1, field_len, x))
|
||||
goto err;
|
||||
if (BN_ucmp(x, group->field) >= 0) {
|
||||
ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (form == POINT_CONVERSION_COMPRESSED) {
|
||||
if (!EC_POINT_set_compressed_coordinates(group, point, x, y_bit, ctx))
|
||||
goto err;
|
||||
} else {
|
||||
if (!BN_bin2bn(buf + 1 + field_len, field_len, y))
|
||||
goto err;
|
||||
if (BN_ucmp(y, group->field) >= 0) {
|
||||
ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
|
||||
goto err;
|
||||
}
|
||||
if (form == POINT_CONVERSION_HYBRID) {
|
||||
if (!group->meth->field_div(group, yxi, y, x, ctx))
|
||||
goto err;
|
||||
if (y_bit != BN_is_odd(yxi)) {
|
||||
ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* EC_POINT_set_affine_coordinates is responsible for checking that
|
||||
* the point is on the curve.
|
||||
*/
|
||||
if (!EC_POINT_set_affine_coordinates(group, point, x, y, ctx))
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
970
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ec2_smpl.c
vendored
Normal file
970
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ec2_smpl.c
vendored
Normal file
|
@ -0,0 +1,970 @@
|
|||
/*
|
||||
* Copyright 2002-2019 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "internal/bn_int.h"
|
||||
#include "ec_lcl.h"
|
||||
|
||||
#ifndef OPENSSL_NO_EC2M
|
||||
|
||||
/*
|
||||
* Initialize a GF(2^m)-based EC_GROUP structure. Note that all other members
|
||||
* are handled by EC_GROUP_new.
|
||||
*/
|
||||
int ec_GF2m_simple_group_init(EC_GROUP *group)
|
||||
{
|
||||
group->field = BN_new();
|
||||
group->a = BN_new();
|
||||
group->b = BN_new();
|
||||
|
||||
if (group->field == NULL || group->a == NULL || group->b == NULL) {
|
||||
BN_free(group->field);
|
||||
BN_free(group->a);
|
||||
BN_free(group->b);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free a GF(2^m)-based EC_GROUP structure. Note that all other members are
|
||||
* handled by EC_GROUP_free.
|
||||
*/
|
||||
void ec_GF2m_simple_group_finish(EC_GROUP *group)
|
||||
{
|
||||
BN_free(group->field);
|
||||
BN_free(group->a);
|
||||
BN_free(group->b);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear and free a GF(2^m)-based EC_GROUP structure. Note that all other
|
||||
* members are handled by EC_GROUP_clear_free.
|
||||
*/
|
||||
void ec_GF2m_simple_group_clear_finish(EC_GROUP *group)
|
||||
{
|
||||
BN_clear_free(group->field);
|
||||
BN_clear_free(group->a);
|
||||
BN_clear_free(group->b);
|
||||
group->poly[0] = 0;
|
||||
group->poly[1] = 0;
|
||||
group->poly[2] = 0;
|
||||
group->poly[3] = 0;
|
||||
group->poly[4] = 0;
|
||||
group->poly[5] = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy a GF(2^m)-based EC_GROUP structure. Note that all other members are
|
||||
* handled by EC_GROUP_copy.
|
||||
*/
|
||||
int ec_GF2m_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src)
|
||||
{
|
||||
if (!BN_copy(dest->field, src->field))
|
||||
return 0;
|
||||
if (!BN_copy(dest->a, src->a))
|
||||
return 0;
|
||||
if (!BN_copy(dest->b, src->b))
|
||||
return 0;
|
||||
dest->poly[0] = src->poly[0];
|
||||
dest->poly[1] = src->poly[1];
|
||||
dest->poly[2] = src->poly[2];
|
||||
dest->poly[3] = src->poly[3];
|
||||
dest->poly[4] = src->poly[4];
|
||||
dest->poly[5] = src->poly[5];
|
||||
if (bn_wexpand(dest->a, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) ==
|
||||
NULL)
|
||||
return 0;
|
||||
if (bn_wexpand(dest->b, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) ==
|
||||
NULL)
|
||||
return 0;
|
||||
bn_set_all_zero(dest->a);
|
||||
bn_set_all_zero(dest->b);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Set the curve parameters of an EC_GROUP structure. */
|
||||
int ec_GF2m_simple_group_set_curve(EC_GROUP *group,
|
||||
const BIGNUM *p, const BIGNUM *a,
|
||||
const BIGNUM *b, BN_CTX *ctx)
|
||||
{
|
||||
int ret = 0, i;
|
||||
|
||||
/* group->field */
|
||||
if (!BN_copy(group->field, p))
|
||||
goto err;
|
||||
i = BN_GF2m_poly2arr(group->field, group->poly, 6) - 1;
|
||||
if ((i != 5) && (i != 3)) {
|
||||
ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE, EC_R_UNSUPPORTED_FIELD);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* group->a */
|
||||
if (!BN_GF2m_mod_arr(group->a, a, group->poly))
|
||||
goto err;
|
||||
if (bn_wexpand(group->a, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2)
|
||||
== NULL)
|
||||
goto err;
|
||||
bn_set_all_zero(group->a);
|
||||
|
||||
/* group->b */
|
||||
if (!BN_GF2m_mod_arr(group->b, b, group->poly))
|
||||
goto err;
|
||||
if (bn_wexpand(group->b, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2)
|
||||
== NULL)
|
||||
goto err;
|
||||
bn_set_all_zero(group->b);
|
||||
|
||||
ret = 1;
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the curve parameters of an EC_GROUP structure. If p, a, or b are NULL
|
||||
* then there values will not be set but the method will return with success.
|
||||
*/
|
||||
int ec_GF2m_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p,
|
||||
BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (p != NULL) {
|
||||
if (!BN_copy(p, group->field))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (a != NULL) {
|
||||
if (!BN_copy(a, group->a))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (b != NULL) {
|
||||
if (!BN_copy(b, group->b))
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets the degree of the field. For a curve over GF(2^m) this is the value
|
||||
* m.
|
||||
*/
|
||||
int ec_GF2m_simple_group_get_degree(const EC_GROUP *group)
|
||||
{
|
||||
return BN_num_bits(group->field) - 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks the discriminant of the curve. y^2 + x*y = x^3 + a*x^2 + b is an
|
||||
* elliptic curve <=> b != 0 (mod p)
|
||||
*/
|
||||
int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *group,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
BIGNUM *b;
|
||||
BN_CTX *new_ctx = NULL;
|
||||
|
||||
if (ctx == NULL) {
|
||||
ctx = new_ctx = BN_CTX_new();
|
||||
if (ctx == NULL) {
|
||||
ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT,
|
||||
ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
BN_CTX_start(ctx);
|
||||
b = BN_CTX_get(ctx);
|
||||
if (b == NULL)
|
||||
goto err;
|
||||
|
||||
if (!BN_GF2m_mod_arr(b, group->b, group->poly))
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* check the discriminant: y^2 + x*y = x^3 + a*x^2 + b is an elliptic
|
||||
* curve <=> b != 0 (mod p)
|
||||
*/
|
||||
if (BN_is_zero(b))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
if (ctx != NULL)
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Initializes an EC_POINT. */
|
||||
int ec_GF2m_simple_point_init(EC_POINT *point)
|
||||
{
|
||||
point->X = BN_new();
|
||||
point->Y = BN_new();
|
||||
point->Z = BN_new();
|
||||
|
||||
if (point->X == NULL || point->Y == NULL || point->Z == NULL) {
|
||||
BN_free(point->X);
|
||||
BN_free(point->Y);
|
||||
BN_free(point->Z);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Frees an EC_POINT. */
|
||||
void ec_GF2m_simple_point_finish(EC_POINT *point)
|
||||
{
|
||||
BN_free(point->X);
|
||||
BN_free(point->Y);
|
||||
BN_free(point->Z);
|
||||
}
|
||||
|
||||
/* Clears and frees an EC_POINT. */
|
||||
void ec_GF2m_simple_point_clear_finish(EC_POINT *point)
|
||||
{
|
||||
BN_clear_free(point->X);
|
||||
BN_clear_free(point->Y);
|
||||
BN_clear_free(point->Z);
|
||||
point->Z_is_one = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy the contents of one EC_POINT into another. Assumes dest is
|
||||
* initialized.
|
||||
*/
|
||||
int ec_GF2m_simple_point_copy(EC_POINT *dest, const EC_POINT *src)
|
||||
{
|
||||
if (!BN_copy(dest->X, src->X))
|
||||
return 0;
|
||||
if (!BN_copy(dest->Y, src->Y))
|
||||
return 0;
|
||||
if (!BN_copy(dest->Z, src->Z))
|
||||
return 0;
|
||||
dest->Z_is_one = src->Z_is_one;
|
||||
dest->curve_name = src->curve_name;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set an EC_POINT to the point at infinity. A point at infinity is
|
||||
* represented by having Z=0.
|
||||
*/
|
||||
int ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *group,
|
||||
EC_POINT *point)
|
||||
{
|
||||
point->Z_is_one = 0;
|
||||
BN_zero(point->Z);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the coordinates of an EC_POINT using affine coordinates. Note that
|
||||
* the simple implementation only uses affine coordinates.
|
||||
*/
|
||||
int ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *group,
|
||||
EC_POINT *point,
|
||||
const BIGNUM *x,
|
||||
const BIGNUM *y, BN_CTX *ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
if (x == NULL || y == NULL) {
|
||||
ECerr(EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES,
|
||||
ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!BN_copy(point->X, x))
|
||||
goto err;
|
||||
BN_set_negative(point->X, 0);
|
||||
if (!BN_copy(point->Y, y))
|
||||
goto err;
|
||||
BN_set_negative(point->Y, 0);
|
||||
if (!BN_copy(point->Z, BN_value_one()))
|
||||
goto err;
|
||||
BN_set_negative(point->Z, 0);
|
||||
point->Z_is_one = 1;
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets the affine coordinates of an EC_POINT. Note that the simple
|
||||
* implementation only uses affine coordinates.
|
||||
*/
|
||||
int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *group,
|
||||
const EC_POINT *point,
|
||||
BIGNUM *x, BIGNUM *y,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (EC_POINT_is_at_infinity(group, point)) {
|
||||
ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES,
|
||||
EC_R_POINT_AT_INFINITY);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (BN_cmp(point->Z, BN_value_one())) {
|
||||
ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES,
|
||||
ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
||||
return 0;
|
||||
}
|
||||
if (x != NULL) {
|
||||
if (!BN_copy(x, point->X))
|
||||
goto err;
|
||||
BN_set_negative(x, 0);
|
||||
}
|
||||
if (y != NULL) {
|
||||
if (!BN_copy(y, point->Y))
|
||||
goto err;
|
||||
BN_set_negative(y, 0);
|
||||
}
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Computes a + b and stores the result in r. r could be a or b, a could be
|
||||
* b. Uses algorithm A.10.2 of IEEE P1363.
|
||||
*/
|
||||
int ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
|
||||
const EC_POINT *b, BN_CTX *ctx)
|
||||
{
|
||||
BN_CTX *new_ctx = NULL;
|
||||
BIGNUM *x0, *y0, *x1, *y1, *x2, *y2, *s, *t;
|
||||
int ret = 0;
|
||||
|
||||
if (EC_POINT_is_at_infinity(group, a)) {
|
||||
if (!EC_POINT_copy(r, b))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (EC_POINT_is_at_infinity(group, b)) {
|
||||
if (!EC_POINT_copy(r, a))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ctx == NULL) {
|
||||
ctx = new_ctx = BN_CTX_new();
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
}
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
x0 = BN_CTX_get(ctx);
|
||||
y0 = BN_CTX_get(ctx);
|
||||
x1 = BN_CTX_get(ctx);
|
||||
y1 = BN_CTX_get(ctx);
|
||||
x2 = BN_CTX_get(ctx);
|
||||
y2 = BN_CTX_get(ctx);
|
||||
s = BN_CTX_get(ctx);
|
||||
t = BN_CTX_get(ctx);
|
||||
if (t == NULL)
|
||||
goto err;
|
||||
|
||||
if (a->Z_is_one) {
|
||||
if (!BN_copy(x0, a->X))
|
||||
goto err;
|
||||
if (!BN_copy(y0, a->Y))
|
||||
goto err;
|
||||
} else {
|
||||
if (!EC_POINT_get_affine_coordinates(group, a, x0, y0, ctx))
|
||||
goto err;
|
||||
}
|
||||
if (b->Z_is_one) {
|
||||
if (!BN_copy(x1, b->X))
|
||||
goto err;
|
||||
if (!BN_copy(y1, b->Y))
|
||||
goto err;
|
||||
} else {
|
||||
if (!EC_POINT_get_affine_coordinates(group, b, x1, y1, ctx))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (BN_GF2m_cmp(x0, x1)) {
|
||||
if (!BN_GF2m_add(t, x0, x1))
|
||||
goto err;
|
||||
if (!BN_GF2m_add(s, y0, y1))
|
||||
goto err;
|
||||
if (!group->meth->field_div(group, s, s, t, ctx))
|
||||
goto err;
|
||||
if (!group->meth->field_sqr(group, x2, s, ctx))
|
||||
goto err;
|
||||
if (!BN_GF2m_add(x2, x2, group->a))
|
||||
goto err;
|
||||
if (!BN_GF2m_add(x2, x2, s))
|
||||
goto err;
|
||||
if (!BN_GF2m_add(x2, x2, t))
|
||||
goto err;
|
||||
} else {
|
||||
if (BN_GF2m_cmp(y0, y1) || BN_is_zero(x1)) {
|
||||
if (!EC_POINT_set_to_infinity(group, r))
|
||||
goto err;
|
||||
ret = 1;
|
||||
goto err;
|
||||
}
|
||||
if (!group->meth->field_div(group, s, y1, x1, ctx))
|
||||
goto err;
|
||||
if (!BN_GF2m_add(s, s, x1))
|
||||
goto err;
|
||||
|
||||
if (!group->meth->field_sqr(group, x2, s, ctx))
|
||||
goto err;
|
||||
if (!BN_GF2m_add(x2, x2, s))
|
||||
goto err;
|
||||
if (!BN_GF2m_add(x2, x2, group->a))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!BN_GF2m_add(y2, x1, x2))
|
||||
goto err;
|
||||
if (!group->meth->field_mul(group, y2, y2, s, ctx))
|
||||
goto err;
|
||||
if (!BN_GF2m_add(y2, y2, x2))
|
||||
goto err;
|
||||
if (!BN_GF2m_add(y2, y2, y1))
|
||||
goto err;
|
||||
|
||||
if (!EC_POINT_set_affine_coordinates(group, r, x2, y2, ctx))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Computes 2 * a and stores the result in r. r could be a. Uses algorithm
|
||||
* A.10.2 of IEEE P1363.
|
||||
*/
|
||||
int ec_GF2m_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
return ec_GF2m_simple_add(group, r, a, a, ctx);
|
||||
}
|
||||
|
||||
int ec_GF2m_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
|
||||
{
|
||||
if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(point->Y))
|
||||
/* point is its own inverse */
|
||||
return 1;
|
||||
|
||||
if (!EC_POINT_make_affine(group, point, ctx))
|
||||
return 0;
|
||||
return BN_GF2m_add(point->Y, point->X, point->Y);
|
||||
}
|
||||
|
||||
/* Indicates whether the given point is the point at infinity. */
|
||||
int ec_GF2m_simple_is_at_infinity(const EC_GROUP *group,
|
||||
const EC_POINT *point)
|
||||
{
|
||||
return BN_is_zero(point->Z);
|
||||
}
|
||||
|
||||
/*-
|
||||
* Determines whether the given EC_POINT is an actual point on the curve defined
|
||||
* in the EC_GROUP. A point is valid if it satisfies the Weierstrass equation:
|
||||
* y^2 + x*y = x^3 + a*x^2 + b.
|
||||
*/
|
||||
int ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
int ret = -1;
|
||||
BN_CTX *new_ctx = NULL;
|
||||
BIGNUM *lh, *y2;
|
||||
int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *,
|
||||
const BIGNUM *, BN_CTX *);
|
||||
int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
|
||||
|
||||
if (EC_POINT_is_at_infinity(group, point))
|
||||
return 1;
|
||||
|
||||
field_mul = group->meth->field_mul;
|
||||
field_sqr = group->meth->field_sqr;
|
||||
|
||||
/* only support affine coordinates */
|
||||
if (!point->Z_is_one)
|
||||
return -1;
|
||||
|
||||
if (ctx == NULL) {
|
||||
ctx = new_ctx = BN_CTX_new();
|
||||
if (ctx == NULL)
|
||||
return -1;
|
||||
}
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
y2 = BN_CTX_get(ctx);
|
||||
lh = BN_CTX_get(ctx);
|
||||
if (lh == NULL)
|
||||
goto err;
|
||||
|
||||
/*-
|
||||
* We have a curve defined by a Weierstrass equation
|
||||
* y^2 + x*y = x^3 + a*x^2 + b.
|
||||
* <=> x^3 + a*x^2 + x*y + b + y^2 = 0
|
||||
* <=> ((x + a) * x + y ) * x + b + y^2 = 0
|
||||
*/
|
||||
if (!BN_GF2m_add(lh, point->X, group->a))
|
||||
goto err;
|
||||
if (!field_mul(group, lh, lh, point->X, ctx))
|
||||
goto err;
|
||||
if (!BN_GF2m_add(lh, lh, point->Y))
|
||||
goto err;
|
||||
if (!field_mul(group, lh, lh, point->X, ctx))
|
||||
goto err;
|
||||
if (!BN_GF2m_add(lh, lh, group->b))
|
||||
goto err;
|
||||
if (!field_sqr(group, y2, point->Y, ctx))
|
||||
goto err;
|
||||
if (!BN_GF2m_add(lh, lh, y2))
|
||||
goto err;
|
||||
ret = BN_is_zero(lh);
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*-
|
||||
* Indicates whether two points are equal.
|
||||
* Return values:
|
||||
* -1 error
|
||||
* 0 equal (in affine coordinates)
|
||||
* 1 not equal
|
||||
*/
|
||||
int ec_GF2m_simple_cmp(const EC_GROUP *group, const EC_POINT *a,
|
||||
const EC_POINT *b, BN_CTX *ctx)
|
||||
{
|
||||
BIGNUM *aX, *aY, *bX, *bY;
|
||||
BN_CTX *new_ctx = NULL;
|
||||
int ret = -1;
|
||||
|
||||
if (EC_POINT_is_at_infinity(group, a)) {
|
||||
return EC_POINT_is_at_infinity(group, b) ? 0 : 1;
|
||||
}
|
||||
|
||||
if (EC_POINT_is_at_infinity(group, b))
|
||||
return 1;
|
||||
|
||||
if (a->Z_is_one && b->Z_is_one) {
|
||||
return ((BN_cmp(a->X, b->X) == 0) && BN_cmp(a->Y, b->Y) == 0) ? 0 : 1;
|
||||
}
|
||||
|
||||
if (ctx == NULL) {
|
||||
ctx = new_ctx = BN_CTX_new();
|
||||
if (ctx == NULL)
|
||||
return -1;
|
||||
}
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
aX = BN_CTX_get(ctx);
|
||||
aY = BN_CTX_get(ctx);
|
||||
bX = BN_CTX_get(ctx);
|
||||
bY = BN_CTX_get(ctx);
|
||||
if (bY == NULL)
|
||||
goto err;
|
||||
|
||||
if (!EC_POINT_get_affine_coordinates(group, a, aX, aY, ctx))
|
||||
goto err;
|
||||
if (!EC_POINT_get_affine_coordinates(group, b, bX, bY, ctx))
|
||||
goto err;
|
||||
ret = ((BN_cmp(aX, bX) == 0) && BN_cmp(aY, bY) == 0) ? 0 : 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Forces the given EC_POINT to internally use affine coordinates. */
|
||||
int ec_GF2m_simple_make_affine(const EC_GROUP *group, EC_POINT *point,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
BN_CTX *new_ctx = NULL;
|
||||
BIGNUM *x, *y;
|
||||
int ret = 0;
|
||||
|
||||
if (point->Z_is_one || EC_POINT_is_at_infinity(group, point))
|
||||
return 1;
|
||||
|
||||
if (ctx == NULL) {
|
||||
ctx = new_ctx = BN_CTX_new();
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
}
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
x = BN_CTX_get(ctx);
|
||||
y = BN_CTX_get(ctx);
|
||||
if (y == NULL)
|
||||
goto err;
|
||||
|
||||
if (!EC_POINT_get_affine_coordinates(group, point, x, y, ctx))
|
||||
goto err;
|
||||
if (!BN_copy(point->X, x))
|
||||
goto err;
|
||||
if (!BN_copy(point->Y, y))
|
||||
goto err;
|
||||
if (!BN_one(point->Z))
|
||||
goto err;
|
||||
point->Z_is_one = 1;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Forces each of the EC_POINTs in the given array to use affine coordinates.
|
||||
*/
|
||||
int ec_GF2m_simple_points_make_affine(const EC_GROUP *group, size_t num,
|
||||
EC_POINT *points[], BN_CTX *ctx)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
if (!group->meth->make_affine(group, points[i], ctx))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Wrapper to simple binary polynomial field multiplication implementation. */
|
||||
int ec_GF2m_simple_field_mul(const EC_GROUP *group, BIGNUM *r,
|
||||
const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
|
||||
{
|
||||
return BN_GF2m_mod_mul_arr(r, a, b, group->poly, ctx);
|
||||
}
|
||||
|
||||
/* Wrapper to simple binary polynomial field squaring implementation. */
|
||||
int ec_GF2m_simple_field_sqr(const EC_GROUP *group, BIGNUM *r,
|
||||
const BIGNUM *a, BN_CTX *ctx)
|
||||
{
|
||||
return BN_GF2m_mod_sqr_arr(r, a, group->poly, ctx);
|
||||
}
|
||||
|
||||
/* Wrapper to simple binary polynomial field division implementation. */
|
||||
int ec_GF2m_simple_field_div(const EC_GROUP *group, BIGNUM *r,
|
||||
const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
|
||||
{
|
||||
return BN_GF2m_mod_div(r, a, b, group->field, ctx);
|
||||
}
|
||||
|
||||
/*-
|
||||
* Lopez-Dahab ladder, pre step.
|
||||
* See e.g. "Guide to ECC" Alg 3.40.
|
||||
* Modified to blind s and r independently.
|
||||
* s:= p, r := 2p
|
||||
*/
|
||||
static
|
||||
int ec_GF2m_simple_ladder_pre(const EC_GROUP *group,
|
||||
EC_POINT *r, EC_POINT *s,
|
||||
EC_POINT *p, BN_CTX *ctx)
|
||||
{
|
||||
/* if p is not affine, something is wrong */
|
||||
if (p->Z_is_one == 0)
|
||||
return 0;
|
||||
|
||||
/* s blinding: make sure lambda (s->Z here) is not zero */
|
||||
do {
|
||||
if (!BN_priv_rand(s->Z, BN_num_bits(group->field) - 1,
|
||||
BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) {
|
||||
ECerr(EC_F_EC_GF2M_SIMPLE_LADDER_PRE, ERR_R_BN_LIB);
|
||||
return 0;
|
||||
}
|
||||
} while (BN_is_zero(s->Z));
|
||||
|
||||
/* if field_encode defined convert between representations */
|
||||
if ((group->meth->field_encode != NULL
|
||||
&& !group->meth->field_encode(group, s->Z, s->Z, ctx))
|
||||
|| !group->meth->field_mul(group, s->X, p->X, s->Z, ctx))
|
||||
return 0;
|
||||
|
||||
/* r blinding: make sure lambda (r->Y here for storage) is not zero */
|
||||
do {
|
||||
if (!BN_priv_rand(r->Y, BN_num_bits(group->field) - 1,
|
||||
BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) {
|
||||
ECerr(EC_F_EC_GF2M_SIMPLE_LADDER_PRE, ERR_R_BN_LIB);
|
||||
return 0;
|
||||
}
|
||||
} while (BN_is_zero(r->Y));
|
||||
|
||||
if ((group->meth->field_encode != NULL
|
||||
&& !group->meth->field_encode(group, r->Y, r->Y, ctx))
|
||||
|| !group->meth->field_sqr(group, r->Z, p->X, ctx)
|
||||
|| !group->meth->field_sqr(group, r->X, r->Z, ctx)
|
||||
|| !BN_GF2m_add(r->X, r->X, group->b)
|
||||
|| !group->meth->field_mul(group, r->Z, r->Z, r->Y, ctx)
|
||||
|| !group->meth->field_mul(group, r->X, r->X, r->Y, ctx))
|
||||
return 0;
|
||||
|
||||
s->Z_is_one = 0;
|
||||
r->Z_is_one = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*-
|
||||
* Ladder step: differential addition-and-doubling, mixed Lopez-Dahab coords.
|
||||
* http://www.hyperelliptic.org/EFD/g12o/auto-code/shortw/xz/ladder/mladd-2003-s.op3
|
||||
* s := r + s, r := 2r
|
||||
*/
|
||||
static
|
||||
int ec_GF2m_simple_ladder_step(const EC_GROUP *group,
|
||||
EC_POINT *r, EC_POINT *s,
|
||||
EC_POINT *p, BN_CTX *ctx)
|
||||
{
|
||||
if (!group->meth->field_mul(group, r->Y, r->Z, s->X, ctx)
|
||||
|| !group->meth->field_mul(group, s->X, r->X, s->Z, ctx)
|
||||
|| !group->meth->field_sqr(group, s->Y, r->Z, ctx)
|
||||
|| !group->meth->field_sqr(group, r->Z, r->X, ctx)
|
||||
|| !BN_GF2m_add(s->Z, r->Y, s->X)
|
||||
|| !group->meth->field_sqr(group, s->Z, s->Z, ctx)
|
||||
|| !group->meth->field_mul(group, s->X, r->Y, s->X, ctx)
|
||||
|| !group->meth->field_mul(group, r->Y, s->Z, p->X, ctx)
|
||||
|| !BN_GF2m_add(s->X, s->X, r->Y)
|
||||
|| !group->meth->field_sqr(group, r->Y, r->Z, ctx)
|
||||
|| !group->meth->field_mul(group, r->Z, r->Z, s->Y, ctx)
|
||||
|| !group->meth->field_sqr(group, s->Y, s->Y, ctx)
|
||||
|| !group->meth->field_mul(group, s->Y, s->Y, group->b, ctx)
|
||||
|| !BN_GF2m_add(r->X, r->Y, s->Y))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*-
|
||||
* Recover affine (x,y) result from Lopez-Dahab r and s, affine p.
|
||||
* See e.g. "Fast Multiplication on Elliptic Curves over GF(2**m)
|
||||
* without Precomputation" (Lopez and Dahab, CHES 1999),
|
||||
* Appendix Alg Mxy.
|
||||
*/
|
||||
static
|
||||
int ec_GF2m_simple_ladder_post(const EC_GROUP *group,
|
||||
EC_POINT *r, EC_POINT *s,
|
||||
EC_POINT *p, BN_CTX *ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
BIGNUM *t0, *t1, *t2 = NULL;
|
||||
|
||||
if (BN_is_zero(r->Z))
|
||||
return EC_POINT_set_to_infinity(group, r);
|
||||
|
||||
if (BN_is_zero(s->Z)) {
|
||||
if (!EC_POINT_copy(r, p)
|
||||
|| !EC_POINT_invert(group, r, ctx)) {
|
||||
ECerr(EC_F_EC_GF2M_SIMPLE_LADDER_POST, ERR_R_EC_LIB);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
t0 = BN_CTX_get(ctx);
|
||||
t1 = BN_CTX_get(ctx);
|
||||
t2 = BN_CTX_get(ctx);
|
||||
if (t2 == NULL) {
|
||||
ECerr(EC_F_EC_GF2M_SIMPLE_LADDER_POST, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!group->meth->field_mul(group, t0, r->Z, s->Z, ctx)
|
||||
|| !group->meth->field_mul(group, t1, p->X, r->Z, ctx)
|
||||
|| !BN_GF2m_add(t1, r->X, t1)
|
||||
|| !group->meth->field_mul(group, t2, p->X, s->Z, ctx)
|
||||
|| !group->meth->field_mul(group, r->Z, r->X, t2, ctx)
|
||||
|| !BN_GF2m_add(t2, t2, s->X)
|
||||
|| !group->meth->field_mul(group, t1, t1, t2, ctx)
|
||||
|| !group->meth->field_sqr(group, t2, p->X, ctx)
|
||||
|| !BN_GF2m_add(t2, p->Y, t2)
|
||||
|| !group->meth->field_mul(group, t2, t2, t0, ctx)
|
||||
|| !BN_GF2m_add(t1, t2, t1)
|
||||
|| !group->meth->field_mul(group, t2, p->X, t0, ctx)
|
||||
|| !group->meth->field_inv(group, t2, t2, ctx)
|
||||
|| !group->meth->field_mul(group, t1, t1, t2, ctx)
|
||||
|| !group->meth->field_mul(group, r->X, r->Z, t2, ctx)
|
||||
|| !BN_GF2m_add(t2, p->X, r->X)
|
||||
|| !group->meth->field_mul(group, t2, t2, t1, ctx)
|
||||
|| !BN_GF2m_add(r->Y, p->Y, t2)
|
||||
|| !BN_one(r->Z))
|
||||
goto err;
|
||||
|
||||
r->Z_is_one = 1;
|
||||
|
||||
/* GF(2^m) field elements should always have BIGNUM::neg = 0 */
|
||||
BN_set_negative(r->X, 0);
|
||||
BN_set_negative(r->Y, 0);
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static
|
||||
int ec_GF2m_simple_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
const BIGNUM *scalar, size_t num,
|
||||
const EC_POINT *points[],
|
||||
const BIGNUM *scalars[],
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
EC_POINT *t = NULL;
|
||||
|
||||
/*-
|
||||
* We limit use of the ladder only to the following cases:
|
||||
* - r := scalar * G
|
||||
* Fixed point mul: scalar != NULL && num == 0;
|
||||
* - r := scalars[0] * points[0]
|
||||
* Variable point mul: scalar == NULL && num == 1;
|
||||
* - r := scalar * G + scalars[0] * points[0]
|
||||
* used, e.g., in ECDSA verification: scalar != NULL && num == 1
|
||||
*
|
||||
* In any other case (num > 1) we use the default wNAF implementation.
|
||||
*
|
||||
* We also let the default implementation handle degenerate cases like group
|
||||
* order or cofactor set to 0.
|
||||
*/
|
||||
if (num > 1 || BN_is_zero(group->order) || BN_is_zero(group->cofactor))
|
||||
return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
|
||||
|
||||
if (scalar != NULL && num == 0)
|
||||
/* Fixed point multiplication */
|
||||
return ec_scalar_mul_ladder(group, r, scalar, NULL, ctx);
|
||||
|
||||
if (scalar == NULL && num == 1)
|
||||
/* Variable point multiplication */
|
||||
return ec_scalar_mul_ladder(group, r, scalars[0], points[0], ctx);
|
||||
|
||||
/*-
|
||||
* Double point multiplication:
|
||||
* r := scalar * G + scalars[0] * points[0]
|
||||
*/
|
||||
|
||||
if ((t = EC_POINT_new(group)) == NULL) {
|
||||
ECerr(EC_F_EC_GF2M_SIMPLE_POINTS_MUL, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ec_scalar_mul_ladder(group, t, scalar, NULL, ctx)
|
||||
|| !ec_scalar_mul_ladder(group, r, scalars[0], points[0], ctx)
|
||||
|| !EC_POINT_add(group, r, t, r, ctx))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
EC_POINT_free(t);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*-
|
||||
* Computes the multiplicative inverse of a in GF(2^m), storing the result in r.
|
||||
* If a is zero (or equivalent), you'll get a EC_R_CANNOT_INVERT error.
|
||||
* SCA hardening is with blinding: BN_GF2m_mod_inv does that.
|
||||
*/
|
||||
static int ec_GF2m_simple_field_inv(const EC_GROUP *group, BIGNUM *r,
|
||||
const BIGNUM *a, BN_CTX *ctx)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!(ret = BN_GF2m_mod_inv(r, a, group->field, ctx)))
|
||||
ECerr(EC_F_EC_GF2M_SIMPLE_FIELD_INV, EC_R_CANNOT_INVERT);
|
||||
return ret;
|
||||
}
|
||||
|
||||
const EC_METHOD *EC_GF2m_simple_method(void)
|
||||
{
|
||||
static const EC_METHOD ret = {
|
||||
EC_FLAGS_DEFAULT_OCT,
|
||||
NID_X9_62_characteristic_two_field,
|
||||
ec_GF2m_simple_group_init,
|
||||
ec_GF2m_simple_group_finish,
|
||||
ec_GF2m_simple_group_clear_finish,
|
||||
ec_GF2m_simple_group_copy,
|
||||
ec_GF2m_simple_group_set_curve,
|
||||
ec_GF2m_simple_group_get_curve,
|
||||
ec_GF2m_simple_group_get_degree,
|
||||
ec_group_simple_order_bits,
|
||||
ec_GF2m_simple_group_check_discriminant,
|
||||
ec_GF2m_simple_point_init,
|
||||
ec_GF2m_simple_point_finish,
|
||||
ec_GF2m_simple_point_clear_finish,
|
||||
ec_GF2m_simple_point_copy,
|
||||
ec_GF2m_simple_point_set_to_infinity,
|
||||
0, /* set_Jprojective_coordinates_GFp */
|
||||
0, /* get_Jprojective_coordinates_GFp */
|
||||
ec_GF2m_simple_point_set_affine_coordinates,
|
||||
ec_GF2m_simple_point_get_affine_coordinates,
|
||||
0, /* point_set_compressed_coordinates */
|
||||
0, /* point2oct */
|
||||
0, /* oct2point */
|
||||
ec_GF2m_simple_add,
|
||||
ec_GF2m_simple_dbl,
|
||||
ec_GF2m_simple_invert,
|
||||
ec_GF2m_simple_is_at_infinity,
|
||||
ec_GF2m_simple_is_on_curve,
|
||||
ec_GF2m_simple_cmp,
|
||||
ec_GF2m_simple_make_affine,
|
||||
ec_GF2m_simple_points_make_affine,
|
||||
ec_GF2m_simple_points_mul,
|
||||
0, /* precompute_mult */
|
||||
0, /* have_precompute_mult */
|
||||
ec_GF2m_simple_field_mul,
|
||||
ec_GF2m_simple_field_sqr,
|
||||
ec_GF2m_simple_field_div,
|
||||
ec_GF2m_simple_field_inv,
|
||||
0, /* field_encode */
|
||||
0, /* field_decode */
|
||||
0, /* field_set_to_one */
|
||||
ec_key_simple_priv2oct,
|
||||
ec_key_simple_oct2priv,
|
||||
0, /* set private */
|
||||
ec_key_simple_generate_key,
|
||||
ec_key_simple_check_key,
|
||||
ec_key_simple_generate_public_key,
|
||||
0, /* keycopy */
|
||||
0, /* keyfinish */
|
||||
ecdh_simple_compute_key,
|
||||
0, /* field_inverse_mod_ord */
|
||||
0, /* blind_coordinates */
|
||||
ec_GF2m_simple_ladder_pre,
|
||||
ec_GF2m_simple_ladder_step,
|
||||
ec_GF2m_simple_ladder_post
|
||||
};
|
||||
|
||||
return &ret;
|
||||
}
|
||||
|
||||
#endif
|
942
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ec_ameth.c
vendored
Normal file
942
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ec_ameth.c
vendored
Normal file
|
@ -0,0 +1,942 @@
|
|||
/*
|
||||
* Copyright 2006-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
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/cms.h>
|
||||
#include <openssl/asn1t.h>
|
||||
#include "internal/asn1_int.h"
|
||||
#include "internal/evp_int.h"
|
||||
#include "ec_lcl.h"
|
||||
|
||||
#ifndef OPENSSL_NO_CMS
|
||||
static int ecdh_cms_decrypt(CMS_RecipientInfo *ri);
|
||||
static int ecdh_cms_encrypt(CMS_RecipientInfo *ri);
|
||||
#endif
|
||||
|
||||
static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key)
|
||||
{
|
||||
const EC_GROUP *group;
|
||||
int nid;
|
||||
if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) {
|
||||
ECerr(EC_F_ECKEY_PARAM2TYPE, EC_R_MISSING_PARAMETERS);
|
||||
return 0;
|
||||
}
|
||||
if (EC_GROUP_get_asn1_flag(group)
|
||||
&& (nid = EC_GROUP_get_curve_name(group)))
|
||||
/* we have a 'named curve' => just set the OID */
|
||||
{
|
||||
*ppval = OBJ_nid2obj(nid);
|
||||
*pptype = V_ASN1_OBJECT;
|
||||
} else { /* explicit parameters */
|
||||
|
||||
ASN1_STRING *pstr = NULL;
|
||||
pstr = ASN1_STRING_new();
|
||||
if (pstr == NULL)
|
||||
return 0;
|
||||
pstr->length = i2d_ECParameters(ec_key, &pstr->data);
|
||||
if (pstr->length <= 0) {
|
||||
ASN1_STRING_free(pstr);
|
||||
ECerr(EC_F_ECKEY_PARAM2TYPE, ERR_R_EC_LIB);
|
||||
return 0;
|
||||
}
|
||||
*ppval = pstr;
|
||||
*pptype = V_ASN1_SEQUENCE;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
|
||||
{
|
||||
EC_KEY *ec_key = pkey->pkey.ec;
|
||||
void *pval = NULL;
|
||||
int ptype;
|
||||
unsigned char *penc = NULL, *p;
|
||||
int penclen;
|
||||
|
||||
if (!eckey_param2type(&ptype, &pval, ec_key)) {
|
||||
ECerr(EC_F_ECKEY_PUB_ENCODE, ERR_R_EC_LIB);
|
||||
return 0;
|
||||
}
|
||||
penclen = i2o_ECPublicKey(ec_key, NULL);
|
||||
if (penclen <= 0)
|
||||
goto err;
|
||||
penc = OPENSSL_malloc(penclen);
|
||||
if (penc == NULL)
|
||||
goto err;
|
||||
p = penc;
|
||||
penclen = i2o_ECPublicKey(ec_key, &p);
|
||||
if (penclen <= 0)
|
||||
goto err;
|
||||
if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC),
|
||||
ptype, pval, penc, penclen))
|
||||
return 1;
|
||||
err:
|
||||
if (ptype == V_ASN1_OBJECT)
|
||||
ASN1_OBJECT_free(pval);
|
||||
else
|
||||
ASN1_STRING_free(pval);
|
||||
OPENSSL_free(penc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static EC_KEY *eckey_type2param(int ptype, const void *pval)
|
||||
{
|
||||
EC_KEY *eckey = NULL;
|
||||
EC_GROUP *group = NULL;
|
||||
|
||||
if (ptype == V_ASN1_SEQUENCE) {
|
||||
const ASN1_STRING *pstr = pval;
|
||||
const unsigned char *pm = pstr->data;
|
||||
int pmlen = pstr->length;
|
||||
|
||||
if ((eckey = d2i_ECParameters(NULL, &pm, pmlen)) == NULL) {
|
||||
ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR);
|
||||
goto ecerr;
|
||||
}
|
||||
} else if (ptype == V_ASN1_OBJECT) {
|
||||
const ASN1_OBJECT *poid = pval;
|
||||
|
||||
/*
|
||||
* type == V_ASN1_OBJECT => the parameters are given by an asn1 OID
|
||||
*/
|
||||
if ((eckey = EC_KEY_new()) == NULL) {
|
||||
ECerr(EC_F_ECKEY_TYPE2PARAM, ERR_R_MALLOC_FAILURE);
|
||||
goto ecerr;
|
||||
}
|
||||
group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid));
|
||||
if (group == NULL)
|
||||
goto ecerr;
|
||||
EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
|
||||
if (EC_KEY_set_group(eckey, group) == 0)
|
||||
goto ecerr;
|
||||
EC_GROUP_free(group);
|
||||
} else {
|
||||
ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR);
|
||||
goto ecerr;
|
||||
}
|
||||
|
||||
return eckey;
|
||||
|
||||
ecerr:
|
||||
EC_KEY_free(eckey);
|
||||
EC_GROUP_free(group);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
|
||||
{
|
||||
const unsigned char *p = NULL;
|
||||
const void *pval;
|
||||
int ptype, pklen;
|
||||
EC_KEY *eckey = NULL;
|
||||
X509_ALGOR *palg;
|
||||
|
||||
if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
|
||||
return 0;
|
||||
X509_ALGOR_get0(NULL, &ptype, &pval, palg);
|
||||
|
||||
eckey = eckey_type2param(ptype, pval);
|
||||
|
||||
if (!eckey) {
|
||||
ECerr(EC_F_ECKEY_PUB_DECODE, ERR_R_EC_LIB);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We have parameters now set public key */
|
||||
if (!o2i_ECPublicKey(&eckey, &p, pklen)) {
|
||||
ECerr(EC_F_ECKEY_PUB_DECODE, EC_R_DECODE_ERROR);
|
||||
goto ecerr;
|
||||
}
|
||||
|
||||
EVP_PKEY_assign_EC_KEY(pkey, eckey);
|
||||
return 1;
|
||||
|
||||
ecerr:
|
||||
EC_KEY_free(eckey);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
|
||||
{
|
||||
int r;
|
||||
const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec);
|
||||
const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec),
|
||||
*pb = EC_KEY_get0_public_key(b->pkey.ec);
|
||||
if (group == NULL || pa == NULL || pb == NULL)
|
||||
return -2;
|
||||
r = EC_POINT_cmp(group, pa, pb, NULL);
|
||||
if (r == 0)
|
||||
return 1;
|
||||
if (r == 1)
|
||||
return 0;
|
||||
return -2;
|
||||
}
|
||||
|
||||
static int eckey_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
|
||||
{
|
||||
const unsigned char *p = NULL;
|
||||
const void *pval;
|
||||
int ptype, pklen;
|
||||
EC_KEY *eckey = NULL;
|
||||
const X509_ALGOR *palg;
|
||||
|
||||
if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
|
||||
return 0;
|
||||
X509_ALGOR_get0(NULL, &ptype, &pval, palg);
|
||||
|
||||
eckey = eckey_type2param(ptype, pval);
|
||||
|
||||
if (!eckey)
|
||||
goto ecliberr;
|
||||
|
||||
/* We have parameters now set private key */
|
||||
if (!d2i_ECPrivateKey(&eckey, &p, pklen)) {
|
||||
ECerr(EC_F_ECKEY_PRIV_DECODE, EC_R_DECODE_ERROR);
|
||||
goto ecerr;
|
||||
}
|
||||
|
||||
EVP_PKEY_assign_EC_KEY(pkey, eckey);
|
||||
return 1;
|
||||
|
||||
ecliberr:
|
||||
ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
|
||||
ecerr:
|
||||
EC_KEY_free(eckey);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
|
||||
{
|
||||
EC_KEY ec_key = *(pkey->pkey.ec);
|
||||
unsigned char *ep, *p;
|
||||
int eplen, ptype;
|
||||
void *pval;
|
||||
unsigned int old_flags;
|
||||
|
||||
if (!eckey_param2type(&ptype, &pval, &ec_key)) {
|
||||
ECerr(EC_F_ECKEY_PRIV_ENCODE, EC_R_DECODE_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* set the private key */
|
||||
|
||||
/*
|
||||
* do not include the parameters in the SEC1 private key see PKCS#11
|
||||
* 12.11
|
||||
*/
|
||||
old_flags = EC_KEY_get_enc_flags(&ec_key);
|
||||
EC_KEY_set_enc_flags(&ec_key, old_flags | EC_PKEY_NO_PARAMETERS);
|
||||
|
||||
eplen = i2d_ECPrivateKey(&ec_key, NULL);
|
||||
if (!eplen) {
|
||||
ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB);
|
||||
return 0;
|
||||
}
|
||||
ep = OPENSSL_malloc(eplen);
|
||||
if (ep == NULL) {
|
||||
ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
p = ep;
|
||||
if (!i2d_ECPrivateKey(&ec_key, &p)) {
|
||||
OPENSSL_free(ep);
|
||||
ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0,
|
||||
ptype, pval, ep, eplen)) {
|
||||
OPENSSL_free(ep);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int int_ec_size(const EVP_PKEY *pkey)
|
||||
{
|
||||
return ECDSA_size(pkey->pkey.ec);
|
||||
}
|
||||
|
||||
static int ec_bits(const EVP_PKEY *pkey)
|
||||
{
|
||||
return EC_GROUP_order_bits(EC_KEY_get0_group(pkey->pkey.ec));
|
||||
}
|
||||
|
||||
static int ec_security_bits(const EVP_PKEY *pkey)
|
||||
{
|
||||
int ecbits = ec_bits(pkey);
|
||||
if (ecbits >= 512)
|
||||
return 256;
|
||||
if (ecbits >= 384)
|
||||
return 192;
|
||||
if (ecbits >= 256)
|
||||
return 128;
|
||||
if (ecbits >= 224)
|
||||
return 112;
|
||||
if (ecbits >= 160)
|
||||
return 80;
|
||||
return ecbits / 2;
|
||||
}
|
||||
|
||||
static int ec_missing_parameters(const EVP_PKEY *pkey)
|
||||
{
|
||||
if (pkey->pkey.ec == NULL || EC_KEY_get0_group(pkey->pkey.ec) == NULL)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ec_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
|
||||
{
|
||||
EC_GROUP *group = EC_GROUP_dup(EC_KEY_get0_group(from->pkey.ec));
|
||||
|
||||
if (group == NULL)
|
||||
return 0;
|
||||
if (to->pkey.ec == NULL) {
|
||||
to->pkey.ec = EC_KEY_new();
|
||||
if (to->pkey.ec == NULL)
|
||||
goto err;
|
||||
}
|
||||
if (EC_KEY_set_group(to->pkey.ec, group) == 0)
|
||||
goto err;
|
||||
EC_GROUP_free(group);
|
||||
return 1;
|
||||
err:
|
||||
EC_GROUP_free(group);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
|
||||
{
|
||||
const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec),
|
||||
*group_b = EC_KEY_get0_group(b->pkey.ec);
|
||||
if (group_a == NULL || group_b == NULL)
|
||||
return -2;
|
||||
if (EC_GROUP_cmp(group_a, group_b, NULL))
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void int_ec_free(EVP_PKEY *pkey)
|
||||
{
|
||||
EC_KEY_free(pkey->pkey.ec);
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
EC_KEY_PRINT_PRIVATE,
|
||||
EC_KEY_PRINT_PUBLIC,
|
||||
EC_KEY_PRINT_PARAM
|
||||
} ec_print_t;
|
||||
|
||||
static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, ec_print_t ktype)
|
||||
{
|
||||
const char *ecstr;
|
||||
unsigned char *priv = NULL, *pub = NULL;
|
||||
size_t privlen = 0, publen = 0;
|
||||
int ret = 0;
|
||||
const EC_GROUP *group;
|
||||
|
||||
if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) {
|
||||
ECerr(EC_F_DO_EC_KEY_PRINT, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ktype != EC_KEY_PRINT_PARAM && EC_KEY_get0_public_key(x) != NULL) {
|
||||
publen = EC_KEY_key2buf(x, EC_KEY_get_conv_form(x), &pub, NULL);
|
||||
if (publen == 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (ktype == EC_KEY_PRINT_PRIVATE && EC_KEY_get0_private_key(x) != NULL) {
|
||||
privlen = EC_KEY_priv2buf(x, &priv);
|
||||
if (privlen == 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (ktype == EC_KEY_PRINT_PRIVATE)
|
||||
ecstr = "Private-Key";
|
||||
else if (ktype == EC_KEY_PRINT_PUBLIC)
|
||||
ecstr = "Public-Key";
|
||||
else
|
||||
ecstr = "ECDSA-Parameters";
|
||||
|
||||
if (!BIO_indent(bp, off, 128))
|
||||
goto err;
|
||||
if (BIO_printf(bp, "%s: (%d bit)\n", ecstr,
|
||||
EC_GROUP_order_bits(group)) <= 0)
|
||||
goto err;
|
||||
|
||||
if (privlen != 0) {
|
||||
if (BIO_printf(bp, "%*spriv:\n", off, "") <= 0)
|
||||
goto err;
|
||||
if (ASN1_buf_print(bp, priv, privlen, off + 4) == 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (publen != 0) {
|
||||
if (BIO_printf(bp, "%*spub:\n", off, "") <= 0)
|
||||
goto err;
|
||||
if (ASN1_buf_print(bp, pub, publen, off + 4) == 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!ECPKParameters_print(bp, group, off))
|
||||
goto err;
|
||||
ret = 1;
|
||||
err:
|
||||
if (!ret)
|
||||
ECerr(EC_F_DO_EC_KEY_PRINT, ERR_R_EC_LIB);
|
||||
OPENSSL_clear_free(priv, privlen);
|
||||
OPENSSL_free(pub);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int eckey_param_decode(EVP_PKEY *pkey,
|
||||
const unsigned char **pder, int derlen)
|
||||
{
|
||||
EC_KEY *eckey;
|
||||
|
||||
if ((eckey = d2i_ECParameters(NULL, pder, derlen)) == NULL) {
|
||||
ECerr(EC_F_ECKEY_PARAM_DECODE, ERR_R_EC_LIB);
|
||||
return 0;
|
||||
}
|
||||
EVP_PKEY_assign_EC_KEY(pkey, eckey);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int eckey_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
|
||||
{
|
||||
return i2d_ECParameters(pkey->pkey.ec, pder);
|
||||
}
|
||||
|
||||
static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
|
||||
ASN1_PCTX *ctx)
|
||||
{
|
||||
return do_EC_KEY_print(bp, pkey->pkey.ec, indent, EC_KEY_PRINT_PARAM);
|
||||
}
|
||||
|
||||
static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
|
||||
ASN1_PCTX *ctx)
|
||||
{
|
||||
return do_EC_KEY_print(bp, pkey->pkey.ec, indent, EC_KEY_PRINT_PUBLIC);
|
||||
}
|
||||
|
||||
static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
|
||||
ASN1_PCTX *ctx)
|
||||
{
|
||||
return do_EC_KEY_print(bp, pkey->pkey.ec, indent, EC_KEY_PRINT_PRIVATE);
|
||||
}
|
||||
|
||||
static int old_ec_priv_decode(EVP_PKEY *pkey,
|
||||
const unsigned char **pder, int derlen)
|
||||
{
|
||||
EC_KEY *ec;
|
||||
|
||||
if ((ec = d2i_ECPrivateKey(NULL, pder, derlen)) == NULL) {
|
||||
ECerr(EC_F_OLD_EC_PRIV_DECODE, EC_R_DECODE_ERROR);
|
||||
return 0;
|
||||
}
|
||||
EVP_PKEY_assign_EC_KEY(pkey, ec);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int old_ec_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
|
||||
{
|
||||
return i2d_ECPrivateKey(pkey->pkey.ec, pder);
|
||||
}
|
||||
|
||||
static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
|
||||
{
|
||||
switch (op) {
|
||||
case ASN1_PKEY_CTRL_PKCS7_SIGN:
|
||||
if (arg1 == 0) {
|
||||
int snid, hnid;
|
||||
X509_ALGOR *alg1, *alg2;
|
||||
PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
|
||||
if (alg1 == NULL || alg1->algorithm == NULL)
|
||||
return -1;
|
||||
hnid = OBJ_obj2nid(alg1->algorithm);
|
||||
if (hnid == NID_undef)
|
||||
return -1;
|
||||
if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
|
||||
return -1;
|
||||
X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
|
||||
}
|
||||
return 1;
|
||||
#ifndef OPENSSL_NO_CMS
|
||||
case ASN1_PKEY_CTRL_CMS_SIGN:
|
||||
if (arg1 == 0) {
|
||||
int snid, hnid;
|
||||
X509_ALGOR *alg1, *alg2;
|
||||
CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2);
|
||||
if (alg1 == NULL || alg1->algorithm == NULL)
|
||||
return -1;
|
||||
hnid = OBJ_obj2nid(alg1->algorithm);
|
||||
if (hnid == NID_undef)
|
||||
return -1;
|
||||
if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
|
||||
return -1;
|
||||
X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
|
||||
}
|
||||
return 1;
|
||||
|
||||
case ASN1_PKEY_CTRL_CMS_ENVELOPE:
|
||||
if (arg1 == 1)
|
||||
return ecdh_cms_decrypt(arg2);
|
||||
else if (arg1 == 0)
|
||||
return ecdh_cms_encrypt(arg2);
|
||||
return -2;
|
||||
|
||||
case ASN1_PKEY_CTRL_CMS_RI_TYPE:
|
||||
*(int *)arg2 = CMS_RECIPINFO_AGREE;
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
|
||||
*(int *)arg2 = NID_sha256;
|
||||
return 1;
|
||||
|
||||
case ASN1_PKEY_CTRL_SET1_TLS_ENCPT:
|
||||
return EC_KEY_oct2key(EVP_PKEY_get0_EC_KEY(pkey), arg2, arg1, NULL);
|
||||
|
||||
case ASN1_PKEY_CTRL_GET1_TLS_ENCPT:
|
||||
return EC_KEY_key2buf(EVP_PKEY_get0_EC_KEY(pkey),
|
||||
POINT_CONVERSION_UNCOMPRESSED, arg2, NULL);
|
||||
|
||||
default:
|
||||
return -2;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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,
|
||||
0,
|
||||
"EC",
|
||||
"OpenSSL EC algorithm",
|
||||
|
||||
eckey_pub_decode,
|
||||
eckey_pub_encode,
|
||||
eckey_pub_cmp,
|
||||
eckey_pub_print,
|
||||
|
||||
eckey_priv_decode,
|
||||
eckey_priv_encode,
|
||||
eckey_priv_print,
|
||||
|
||||
int_ec_size,
|
||||
ec_bits,
|
||||
ec_security_bits,
|
||||
|
||||
eckey_param_decode,
|
||||
eckey_param_encode,
|
||||
ec_missing_parameters,
|
||||
ec_copy_parameters,
|
||||
ec_cmp_parameters,
|
||||
eckey_param_print,
|
||||
0,
|
||||
|
||||
int_ec_free,
|
||||
ec_pkey_ctrl,
|
||||
old_ec_priv_decode,
|
||||
old_ec_priv_encode,
|
||||
|
||||
0, 0, 0,
|
||||
|
||||
ec_pkey_check,
|
||||
ec_pkey_public_check,
|
||||
ec_pkey_param_check
|
||||
};
|
||||
|
||||
#if !defined(OPENSSL_NO_SM2)
|
||||
const EVP_PKEY_ASN1_METHOD sm2_asn1_meth = {
|
||||
EVP_PKEY_SM2,
|
||||
EVP_PKEY_EC,
|
||||
ASN1_PKEY_ALIAS
|
||||
};
|
||||
#endif
|
||||
|
||||
int EC_KEY_print(BIO *bp, const EC_KEY *x, int off)
|
||||
{
|
||||
int private = EC_KEY_get0_private_key(x) != NULL;
|
||||
|
||||
return do_EC_KEY_print(bp, x, off,
|
||||
private ? EC_KEY_PRINT_PRIVATE : EC_KEY_PRINT_PUBLIC);
|
||||
}
|
||||
|
||||
int ECParameters_print(BIO *bp, const EC_KEY *x)
|
||||
{
|
||||
return do_EC_KEY_print(bp, x, 4, EC_KEY_PRINT_PARAM);
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_CMS
|
||||
|
||||
static int ecdh_cms_set_peerkey(EVP_PKEY_CTX *pctx,
|
||||
X509_ALGOR *alg, ASN1_BIT_STRING *pubkey)
|
||||
{
|
||||
const ASN1_OBJECT *aoid;
|
||||
int atype;
|
||||
const void *aval;
|
||||
int rv = 0;
|
||||
EVP_PKEY *pkpeer = NULL;
|
||||
EC_KEY *ecpeer = NULL;
|
||||
const unsigned char *p;
|
||||
int plen;
|
||||
X509_ALGOR_get0(&aoid, &atype, &aval, alg);
|
||||
if (OBJ_obj2nid(aoid) != NID_X9_62_id_ecPublicKey)
|
||||
goto err;
|
||||
/* If absent parameters get group from main key */
|
||||
if (atype == V_ASN1_UNDEF || atype == V_ASN1_NULL) {
|
||||
const EC_GROUP *grp;
|
||||
EVP_PKEY *pk;
|
||||
pk = EVP_PKEY_CTX_get0_pkey(pctx);
|
||||
if (!pk)
|
||||
goto err;
|
||||
grp = EC_KEY_get0_group(pk->pkey.ec);
|
||||
ecpeer = EC_KEY_new();
|
||||
if (ecpeer == NULL)
|
||||
goto err;
|
||||
if (!EC_KEY_set_group(ecpeer, grp))
|
||||
goto err;
|
||||
} else {
|
||||
ecpeer = eckey_type2param(atype, aval);
|
||||
if (!ecpeer)
|
||||
goto err;
|
||||
}
|
||||
/* We have parameters now set public key */
|
||||
plen = ASN1_STRING_length(pubkey);
|
||||
p = ASN1_STRING_get0_data(pubkey);
|
||||
if (!p || !plen)
|
||||
goto err;
|
||||
if (!o2i_ECPublicKey(&ecpeer, &p, plen))
|
||||
goto err;
|
||||
pkpeer = EVP_PKEY_new();
|
||||
if (pkpeer == NULL)
|
||||
goto err;
|
||||
EVP_PKEY_set1_EC_KEY(pkpeer, ecpeer);
|
||||
if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0)
|
||||
rv = 1;
|
||||
err:
|
||||
EC_KEY_free(ecpeer);
|
||||
EVP_PKEY_free(pkpeer);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* Set KDF parameters based on KDF NID */
|
||||
static int ecdh_cms_set_kdf_param(EVP_PKEY_CTX *pctx, int eckdf_nid)
|
||||
{
|
||||
int kdf_nid, kdfmd_nid, cofactor;
|
||||
const EVP_MD *kdf_md;
|
||||
if (eckdf_nid == NID_undef)
|
||||
return 0;
|
||||
|
||||
/* Lookup KDF type, cofactor mode and digest */
|
||||
if (!OBJ_find_sigid_algs(eckdf_nid, &kdfmd_nid, &kdf_nid))
|
||||
return 0;
|
||||
|
||||
if (kdf_nid == NID_dh_std_kdf)
|
||||
cofactor = 0;
|
||||
else if (kdf_nid == NID_dh_cofactor_kdf)
|
||||
cofactor = 1;
|
||||
else
|
||||
return 0;
|
||||
|
||||
if (EVP_PKEY_CTX_set_ecdh_cofactor_mode(pctx, cofactor) <= 0)
|
||||
return 0;
|
||||
|
||||
if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, EVP_PKEY_ECDH_KDF_X9_63) <= 0)
|
||||
return 0;
|
||||
|
||||
kdf_md = EVP_get_digestbynid(kdfmd_nid);
|
||||
if (!kdf_md)
|
||||
return 0;
|
||||
|
||||
if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ecdh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri)
|
||||
{
|
||||
int rv = 0;
|
||||
|
||||
X509_ALGOR *alg, *kekalg = NULL;
|
||||
ASN1_OCTET_STRING *ukm;
|
||||
const unsigned char *p;
|
||||
unsigned char *der = NULL;
|
||||
int plen, keylen;
|
||||
const EVP_CIPHER *kekcipher;
|
||||
EVP_CIPHER_CTX *kekctx;
|
||||
|
||||
if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm))
|
||||
return 0;
|
||||
|
||||
if (!ecdh_cms_set_kdf_param(pctx, OBJ_obj2nid(alg->algorithm))) {
|
||||
ECerr(EC_F_ECDH_CMS_SET_SHARED_INFO, EC_R_KDF_PARAMETER_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (alg->parameter->type != V_ASN1_SEQUENCE)
|
||||
return 0;
|
||||
|
||||
p = alg->parameter->value.sequence->data;
|
||||
plen = alg->parameter->value.sequence->length;
|
||||
kekalg = d2i_X509_ALGOR(NULL, &p, plen);
|
||||
if (!kekalg)
|
||||
goto err;
|
||||
kekctx = CMS_RecipientInfo_kari_get0_ctx(ri);
|
||||
if (!kekctx)
|
||||
goto err;
|
||||
kekcipher = EVP_get_cipherbyobj(kekalg->algorithm);
|
||||
if (!kekcipher || EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE)
|
||||
goto err;
|
||||
if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, NULL))
|
||||
goto err;
|
||||
if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0)
|
||||
goto err;
|
||||
|
||||
keylen = EVP_CIPHER_CTX_key_length(kekctx);
|
||||
if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0)
|
||||
goto err;
|
||||
|
||||
plen = CMS_SharedInfo_encode(&der, kekalg, ukm, keylen);
|
||||
|
||||
if (!plen)
|
||||
goto err;
|
||||
|
||||
if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, der, plen) <= 0)
|
||||
goto err;
|
||||
der = NULL;
|
||||
|
||||
rv = 1;
|
||||
err:
|
||||
X509_ALGOR_free(kekalg);
|
||||
OPENSSL_free(der);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int ecdh_cms_decrypt(CMS_RecipientInfo *ri)
|
||||
{
|
||||
EVP_PKEY_CTX *pctx;
|
||||
pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
|
||||
if (!pctx)
|
||||
return 0;
|
||||
/* See if we need to set peer key */
|
||||
if (!EVP_PKEY_CTX_get0_peerkey(pctx)) {
|
||||
X509_ALGOR *alg;
|
||||
ASN1_BIT_STRING *pubkey;
|
||||
if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &alg, &pubkey,
|
||||
NULL, NULL, NULL))
|
||||
return 0;
|
||||
if (!alg || !pubkey)
|
||||
return 0;
|
||||
if (!ecdh_cms_set_peerkey(pctx, alg, pubkey)) {
|
||||
ECerr(EC_F_ECDH_CMS_DECRYPT, EC_R_PEER_KEY_ERROR);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/* Set ECDH derivation parameters and initialise unwrap context */
|
||||
if (!ecdh_cms_set_shared_info(pctx, ri)) {
|
||||
ECerr(EC_F_ECDH_CMS_DECRYPT, EC_R_SHARED_INFO_ERROR);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ecdh_cms_encrypt(CMS_RecipientInfo *ri)
|
||||
{
|
||||
EVP_PKEY_CTX *pctx;
|
||||
EVP_PKEY *pkey;
|
||||
EVP_CIPHER_CTX *ctx;
|
||||
int keylen;
|
||||
X509_ALGOR *talg, *wrap_alg = NULL;
|
||||
const ASN1_OBJECT *aoid;
|
||||
ASN1_BIT_STRING *pubkey;
|
||||
ASN1_STRING *wrap_str;
|
||||
ASN1_OCTET_STRING *ukm;
|
||||
unsigned char *penc = NULL;
|
||||
int penclen;
|
||||
int rv = 0;
|
||||
int ecdh_nid, kdf_type, kdf_nid, wrap_nid;
|
||||
const EVP_MD *kdf_md;
|
||||
pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
|
||||
if (!pctx)
|
||||
return 0;
|
||||
/* Get ephemeral key */
|
||||
pkey = EVP_PKEY_CTX_get0_pkey(pctx);
|
||||
if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey,
|
||||
NULL, NULL, NULL))
|
||||
goto err;
|
||||
X509_ALGOR_get0(&aoid, NULL, NULL, talg);
|
||||
/* Is everything uninitialised? */
|
||||
if (aoid == OBJ_nid2obj(NID_undef)) {
|
||||
|
||||
EC_KEY *eckey = pkey->pkey.ec;
|
||||
/* Set the key */
|
||||
unsigned char *p;
|
||||
|
||||
penclen = i2o_ECPublicKey(eckey, NULL);
|
||||
if (penclen <= 0)
|
||||
goto err;
|
||||
penc = OPENSSL_malloc(penclen);
|
||||
if (penc == NULL)
|
||||
goto err;
|
||||
p = penc;
|
||||
penclen = i2o_ECPublicKey(eckey, &p);
|
||||
if (penclen <= 0)
|
||||
goto err;
|
||||
ASN1_STRING_set0(pubkey, penc, penclen);
|
||||
pubkey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
|
||||
pubkey->flags |= ASN1_STRING_FLAG_BITS_LEFT;
|
||||
|
||||
penc = NULL;
|
||||
X509_ALGOR_set0(talg, OBJ_nid2obj(NID_X9_62_id_ecPublicKey),
|
||||
V_ASN1_UNDEF, NULL);
|
||||
}
|
||||
|
||||
/* See if custom parameters set */
|
||||
kdf_type = EVP_PKEY_CTX_get_ecdh_kdf_type(pctx);
|
||||
if (kdf_type <= 0)
|
||||
goto err;
|
||||
if (!EVP_PKEY_CTX_get_ecdh_kdf_md(pctx, &kdf_md))
|
||||
goto err;
|
||||
ecdh_nid = EVP_PKEY_CTX_get_ecdh_cofactor_mode(pctx);
|
||||
if (ecdh_nid < 0)
|
||||
goto err;
|
||||
else if (ecdh_nid == 0)
|
||||
ecdh_nid = NID_dh_std_kdf;
|
||||
else if (ecdh_nid == 1)
|
||||
ecdh_nid = NID_dh_cofactor_kdf;
|
||||
|
||||
if (kdf_type == EVP_PKEY_ECDH_KDF_NONE) {
|
||||
kdf_type = EVP_PKEY_ECDH_KDF_X9_63;
|
||||
if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, kdf_type) <= 0)
|
||||
goto err;
|
||||
} else
|
||||
/* Unknown KDF */
|
||||
goto err;
|
||||
if (kdf_md == NULL) {
|
||||
/* Fixme later for better MD */
|
||||
kdf_md = EVP_sha1();
|
||||
if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm))
|
||||
goto err;
|
||||
|
||||
/* Lookup NID for KDF+cofactor+digest */
|
||||
|
||||
if (!OBJ_find_sigid_by_algs(&kdf_nid, EVP_MD_type(kdf_md), ecdh_nid))
|
||||
goto err;
|
||||
/* Get wrap NID */
|
||||
ctx = CMS_RecipientInfo_kari_get0_ctx(ri);
|
||||
wrap_nid = EVP_CIPHER_CTX_type(ctx);
|
||||
keylen = EVP_CIPHER_CTX_key_length(ctx);
|
||||
|
||||
/* Package wrap algorithm in an AlgorithmIdentifier */
|
||||
|
||||
wrap_alg = X509_ALGOR_new();
|
||||
if (wrap_alg == NULL)
|
||||
goto err;
|
||||
wrap_alg->algorithm = OBJ_nid2obj(wrap_nid);
|
||||
wrap_alg->parameter = ASN1_TYPE_new();
|
||||
if (wrap_alg->parameter == NULL)
|
||||
goto err;
|
||||
if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0)
|
||||
goto err;
|
||||
if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef) {
|
||||
ASN1_TYPE_free(wrap_alg->parameter);
|
||||
wrap_alg->parameter = NULL;
|
||||
}
|
||||
|
||||
if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0)
|
||||
goto err;
|
||||
|
||||
penclen = CMS_SharedInfo_encode(&penc, wrap_alg, ukm, keylen);
|
||||
|
||||
if (!penclen)
|
||||
goto err;
|
||||
|
||||
if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, penc, penclen) <= 0)
|
||||
goto err;
|
||||
penc = NULL;
|
||||
|
||||
/*
|
||||
* Now need to wrap encoding of wrap AlgorithmIdentifier into parameter
|
||||
* of another AlgorithmIdentifier.
|
||||
*/
|
||||
penclen = i2d_X509_ALGOR(wrap_alg, &penc);
|
||||
if (!penc || !penclen)
|
||||
goto err;
|
||||
wrap_str = ASN1_STRING_new();
|
||||
if (wrap_str == NULL)
|
||||
goto err;
|
||||
ASN1_STRING_set0(wrap_str, penc, penclen);
|
||||
penc = NULL;
|
||||
X509_ALGOR_set0(talg, OBJ_nid2obj(kdf_nid), V_ASN1_SEQUENCE, wrap_str);
|
||||
|
||||
rv = 1;
|
||||
|
||||
err:
|
||||
OPENSSL_free(penc);
|
||||
X509_ALGOR_free(wrap_alg);
|
||||
return rv;
|
||||
}
|
||||
|
||||
#endif
|
1221
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ec_asn1.c
vendored
Normal file
1221
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ec_asn1.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
72
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ec_check.c
vendored
Normal file
72
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ec_check.c
vendored
Normal file
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright 2002-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
|
||||
*/
|
||||
|
||||
#include "ec_lcl.h"
|
||||
#include <openssl/err.h>
|
||||
|
||||
int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
const BIGNUM *order;
|
||||
BN_CTX *new_ctx = NULL;
|
||||
EC_POINT *point = NULL;
|
||||
|
||||
/* Custom curves assumed to be correct */
|
||||
if ((group->meth->flags & EC_FLAGS_CUSTOM_CURVE) != 0)
|
||||
return 1;
|
||||
|
||||
if (ctx == NULL) {
|
||||
ctx = new_ctx = BN_CTX_new();
|
||||
if (ctx == NULL) {
|
||||
ECerr(EC_F_EC_GROUP_CHECK, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
/* check the discriminant */
|
||||
if (!EC_GROUP_check_discriminant(group, ctx)) {
|
||||
ECerr(EC_F_EC_GROUP_CHECK, EC_R_DISCRIMINANT_IS_ZERO);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* check the generator */
|
||||
if (group->generator == NULL) {
|
||||
ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_GENERATOR);
|
||||
goto err;
|
||||
}
|
||||
if (EC_POINT_is_on_curve(group, group->generator, ctx) <= 0) {
|
||||
ECerr(EC_F_EC_GROUP_CHECK, EC_R_POINT_IS_NOT_ON_CURVE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* check the order of the generator */
|
||||
if ((point = EC_POINT_new(group)) == NULL)
|
||||
goto err;
|
||||
order = EC_GROUP_get0_order(group);
|
||||
if (order == NULL)
|
||||
goto err;
|
||||
if (BN_is_zero(order)) {
|
||||
ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_ORDER);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!EC_POINT_mul(group, point, order, NULL, NULL, ctx))
|
||||
goto err;
|
||||
if (!EC_POINT_is_at_infinity(group, point)) {
|
||||
ECerr(EC_F_EC_GROUP_CHECK, EC_R_INVALID_GROUP_ORDER);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_free(new_ctx);
|
||||
EC_POINT_free(point);
|
||||
return ret;
|
||||
}
|
3199
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ec_curve.c
vendored
Normal file
3199
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ec_curve.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
82
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ec_cvt.c
vendored
Normal file
82
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ec_cvt.c
vendored
Normal file
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include "ec_lcl.h"
|
||||
|
||||
EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
|
||||
const BIGNUM *b, BN_CTX *ctx)
|
||||
{
|
||||
const EC_METHOD *meth;
|
||||
EC_GROUP *ret;
|
||||
|
||||
#if defined(OPENSSL_BN_ASM_MONT)
|
||||
/*
|
||||
* This might appear controversial, but the fact is that generic
|
||||
* prime method was observed to deliver better performance even
|
||||
* for NIST primes on a range of platforms, e.g.: 60%-15%
|
||||
* improvement on IA-64, ~25% on ARM, 30%-90% on P4, 20%-25%
|
||||
* in 32-bit build and 35%--12% in 64-bit build on Core2...
|
||||
* Coefficients are relative to optimized bn_nist.c for most
|
||||
* intensive ECDSA verify and ECDH operations for 192- and 521-
|
||||
* bit keys respectively. Choice of these boundary values is
|
||||
* arguable, because the dependency of improvement coefficient
|
||||
* from key length is not a "monotone" curve. For example while
|
||||
* 571-bit result is 23% on ARM, 384-bit one is -1%. But it's
|
||||
* generally faster, sometimes "respectfully" faster, sometimes
|
||||
* "tolerably" slower... What effectively happens is that loop
|
||||
* with bn_mul_add_words is put against bn_mul_mont, and the
|
||||
* latter "wins" on short vectors. Correct solution should be
|
||||
* implementing dedicated NxN multiplication subroutines for
|
||||
* small N. But till it materializes, let's stick to generic
|
||||
* prime method...
|
||||
* <appro>
|
||||
*/
|
||||
meth = EC_GFp_mont_method();
|
||||
#else
|
||||
if (BN_nist_mod_func(p))
|
||||
meth = EC_GFp_nist_method();
|
||||
else
|
||||
meth = EC_GFp_mont_method();
|
||||
#endif
|
||||
|
||||
ret = EC_GROUP_new(meth);
|
||||
if (ret == NULL)
|
||||
return NULL;
|
||||
|
||||
if (!EC_GROUP_set_curve(ret, p, a, b, ctx)) {
|
||||
EC_GROUP_clear_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_EC2M
|
||||
EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a,
|
||||
const BIGNUM *b, BN_CTX *ctx)
|
||||
{
|
||||
const EC_METHOD *meth;
|
||||
EC_GROUP *ret;
|
||||
|
||||
meth = EC_GF2m_simple_method();
|
||||
|
||||
ret = EC_GROUP_new(meth);
|
||||
if (ret == NULL)
|
||||
return NULL;
|
||||
|
||||
if (!EC_GROUP_set_curve(ret, p, a, b, ctx)) {
|
||||
EC_GROUP_clear_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
394
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ec_err.c
vendored
Normal file
394
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ec_err.c
vendored
Normal file
|
@ -0,0 +1,394 @@
|
|||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2019 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
|
||||
*/
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/ecerr.h>
|
||||
|
||||
#ifndef OPENSSL_NO_ERR
|
||||
|
||||
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_PACK(ERR_LIB_EC, EC_F_ECP_NISTZ256_MULT_PRECOMPUTE, 0),
|
||||
"ecp_nistz256_mult_precompute"},
|
||||
{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_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_FIELD_INV, 0),
|
||||
"ec_GF2m_simple_field_inv"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT, 0),
|
||||
"ec_GF2m_simple_group_check_discriminant"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE, 0),
|
||||
"ec_GF2m_simple_group_set_curve"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_LADDER_POST, 0),
|
||||
"ec_GF2m_simple_ladder_post"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_LADDER_PRE, 0),
|
||||
"ec_GF2m_simple_ladder_pre"},
|
||||
{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_POINTS_MUL, 0),
|
||||
"ec_GF2m_simple_points_mul"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES, 0),
|
||||
"ec_GF2m_simple_point_get_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_PACK(ERR_LIB_EC, EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, 0),
|
||||
"ec_GF2m_simple_set_compressed_coordinates"},
|
||||
{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_INV, 0),
|
||||
"ec_GFp_mont_field_inv"},
|
||||
{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_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_PACK(ERR_LIB_EC, EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE, 0),
|
||||
"ec_GFp_nistp224_group_set_curve"},
|
||||
{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_PACK(ERR_LIB_EC, EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE, 0),
|
||||
"ec_GFp_nistp256_group_set_curve"},
|
||||
{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_PACK(ERR_LIB_EC, EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE, 0),
|
||||
"ec_GFp_nistp521_group_set_curve"},
|
||||
{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_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_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_BLIND_COORDINATES, 0),
|
||||
"ec_GFp_simple_blind_coordinates"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_FIELD_INV, 0),
|
||||
"ec_GFp_simple_field_inv"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT, 0),
|
||||
"ec_GFp_simple_group_check_discriminant"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE, 0),
|
||||
"ec_GFp_simple_group_set_curve"},
|
||||
{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_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES, 0),
|
||||
"ec_GFp_simple_point_get_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_PACK(ERR_LIB_EC, EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, 0),
|
||||
"ec_GFp_simple_set_compressed_coordinates"},
|
||||
{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_PACK(ERR_LIB_EC, EC_F_EC_GROUP_COPY, 0), "EC_GROUP_copy"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_GET_CURVE, 0), "EC_GROUP_get_curve"},
|
||||
{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_PACK(ERR_LIB_EC, EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS, 0),
|
||||
"EC_GROUP_get_pentanomial_basis"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_GET_TRINOMIAL_BASIS, 0),
|
||||
"EC_GROUP_get_trinomial_basis"},
|
||||
{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_PACK(ERR_LIB_EC, EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS, 0),
|
||||
"EC_GROUP_new_from_ecpkparameters"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_GROUP_SET_CURVE, 0), "EC_GROUP_set_curve"},
|
||||
{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_GROUP_SET_SEED, 0), "EC_GROUP_set_seed"},
|
||||
{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_PRIV2BUF, 0), "EC_KEY_priv2buf"},
|
||||
{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_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_POINTS_MUL, 0), "EC_POINTs_mul"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_ADD, 0), "EC_POINT_add"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_BN2POINT, 0), "EC_POINT_bn2point"},
|
||||
{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, 0),
|
||||
"EC_POINT_get_affine_coordinates"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M, 0),
|
||||
"EC_POINT_get_affine_coordinates_GF2m"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP, 0),
|
||||
"EC_POINT_get_affine_coordinates_GFp"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, 0),
|
||||
"EC_POINT_get_Jprojective_coordinates_GFp"},
|
||||
{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_POINT2BUF, 0), "EC_POINT_point2buf"},
|
||||
{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, 0),
|
||||
"EC_POINT_set_affine_coordinates"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M, 0),
|
||||
"EC_POINT_set_affine_coordinates_GF2m"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP, 0),
|
||||
"EC_POINT_set_affine_coordinates_GFp"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_SET_COMPRESSED_COORDINATES, 0),
|
||||
"EC_POINT_set_compressed_coordinates"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M, 0),
|
||||
"EC_POINT_set_compressed_coordinates_GF2m"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, 0),
|
||||
"EC_POINT_set_compressed_coordinates_GFp"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, 0),
|
||||
"EC_POINT_set_Jprojective_coordinates_GFp"},
|
||||
{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_SCALAR_MUL_LADDER, 0),
|
||||
"ec_scalar_mul_ladder"},
|
||||
{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_ECD_DIGESTSIGN25519, 0),
|
||||
"pkey_ecd_digestsign25519"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_PKEY_ECD_DIGESTSIGN448, 0),
|
||||
"pkey_ecd_digestsign448"},
|
||||
{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_INIT, 0), "pkey_ec_init"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_KDF_DERIVE, 0), "pkey_ec_kdf_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"},
|
||||
{ERR_PACK(ERR_LIB_EC, EC_F_VALIDATE_ECX_DERIVE, 0), "validate_ecx_derive"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
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_CANNOT_INVERT), "cannot invert"},
|
||||
{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_LADDER_POST_FAILURE), "ladder post failure"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_LADDER_PRE_FAILURE), "ladder pre failure"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_LADDER_STEP_FAILURE), "ladder step failure"},
|
||||
{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_COORDINATES_BLIND_FAILURE),
|
||||
"point coordinates blind failure"},
|
||||
{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_COFACTOR), "unknown cofactor"},
|
||||
{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}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
int ERR_load_EC_strings(void)
|
||||
{
|
||||
#ifndef OPENSSL_NO_ERR
|
||||
if (ERR_func_error_string(EC_str_functs[0].error) == NULL) {
|
||||
ERR_load_strings_const(EC_str_functs);
|
||||
ERR_load_strings_const(EC_str_reasons);
|
||||
}
|
||||
#endif
|
||||
return 1;
|
||||
}
|
618
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ec_key.c
vendored
Normal file
618
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ec_key.c
vendored
Normal file
|
@ -0,0 +1,618 @@
|
|||
/*
|
||||
* Copyright 2002-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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include "internal/cryptlib.h"
|
||||
#include <string.h>
|
||||
#include "ec_lcl.h"
|
||||
#include "internal/refcount.h"
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/engine.h>
|
||||
|
||||
EC_KEY *EC_KEY_new(void)
|
||||
{
|
||||
return EC_KEY_new_method(NULL);
|
||||
}
|
||||
|
||||
EC_KEY *EC_KEY_new_by_curve_name(int nid)
|
||||
{
|
||||
EC_KEY *ret = EC_KEY_new();
|
||||
if (ret == NULL)
|
||||
return NULL;
|
||||
ret->group = EC_GROUP_new_by_curve_name(nid);
|
||||
if (ret->group == NULL) {
|
||||
EC_KEY_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
if (ret->meth->set_group != NULL
|
||||
&& ret->meth->set_group(ret, ret->group) == 0) {
|
||||
EC_KEY_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void EC_KEY_free(EC_KEY *r)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (r == NULL)
|
||||
return;
|
||||
|
||||
CRYPTO_DOWN_REF(&r->references, &i, r->lock);
|
||||
REF_PRINT_COUNT("EC_KEY", r);
|
||||
if (i > 0)
|
||||
return;
|
||||
REF_ASSERT_ISNT(i < 0);
|
||||
|
||||
if (r->meth != NULL && r->meth->finish != NULL)
|
||||
r->meth->finish(r);
|
||||
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
ENGINE_finish(r->engine);
|
||||
#endif
|
||||
|
||||
if (r->group && r->group->meth->keyfinish)
|
||||
r->group->meth->keyfinish(r);
|
||||
|
||||
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_EC_KEY, r, &r->ex_data);
|
||||
CRYPTO_THREAD_lock_free(r->lock);
|
||||
EC_GROUP_free(r->group);
|
||||
EC_POINT_free(r->pub_key);
|
||||
BN_clear_free(r->priv_key);
|
||||
|
||||
OPENSSL_clear_free((void *)r, sizeof(EC_KEY));
|
||||
}
|
||||
|
||||
EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src)
|
||||
{
|
||||
if (dest == NULL || src == NULL) {
|
||||
ECerr(EC_F_EC_KEY_COPY, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return NULL;
|
||||
}
|
||||
if (src->meth != dest->meth) {
|
||||
if (dest->meth->finish != NULL)
|
||||
dest->meth->finish(dest);
|
||||
if (dest->group && dest->group->meth->keyfinish)
|
||||
dest->group->meth->keyfinish(dest);
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
if (ENGINE_finish(dest->engine) == 0)
|
||||
return 0;
|
||||
dest->engine = NULL;
|
||||
#endif
|
||||
}
|
||||
/* copy the parameters */
|
||||
if (src->group != NULL) {
|
||||
const EC_METHOD *meth = EC_GROUP_method_of(src->group);
|
||||
/* clear the old group */
|
||||
EC_GROUP_free(dest->group);
|
||||
dest->group = EC_GROUP_new(meth);
|
||||
if (dest->group == NULL)
|
||||
return NULL;
|
||||
if (!EC_GROUP_copy(dest->group, src->group))
|
||||
return NULL;
|
||||
|
||||
/* copy the public key */
|
||||
if (src->pub_key != NULL) {
|
||||
EC_POINT_free(dest->pub_key);
|
||||
dest->pub_key = EC_POINT_new(src->group);
|
||||
if (dest->pub_key == NULL)
|
||||
return NULL;
|
||||
if (!EC_POINT_copy(dest->pub_key, src->pub_key))
|
||||
return NULL;
|
||||
}
|
||||
/* copy the private key */
|
||||
if (src->priv_key != NULL) {
|
||||
if (dest->priv_key == NULL) {
|
||||
dest->priv_key = BN_new();
|
||||
if (dest->priv_key == NULL)
|
||||
return NULL;
|
||||
}
|
||||
if (!BN_copy(dest->priv_key, src->priv_key))
|
||||
return NULL;
|
||||
if (src->group->meth->keycopy
|
||||
&& src->group->meth->keycopy(dest, src) == 0)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* copy the rest */
|
||||
dest->enc_flag = src->enc_flag;
|
||||
dest->conv_form = src->conv_form;
|
||||
dest->version = src->version;
|
||||
dest->flags = src->flags;
|
||||
if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_EC_KEY,
|
||||
&dest->ex_data, &src->ex_data))
|
||||
return NULL;
|
||||
|
||||
if (src->meth != dest->meth) {
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
if (src->engine != NULL && ENGINE_init(src->engine) == 0)
|
||||
return NULL;
|
||||
dest->engine = src->engine;
|
||||
#endif
|
||||
dest->meth = src->meth;
|
||||
}
|
||||
|
||||
if (src->meth->copy != NULL && src->meth->copy(dest, src) == 0)
|
||||
return NULL;
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
EC_KEY *EC_KEY_dup(const EC_KEY *ec_key)
|
||||
{
|
||||
EC_KEY *ret = EC_KEY_new_method(ec_key->engine);
|
||||
|
||||
if (ret == NULL)
|
||||
return NULL;
|
||||
|
||||
if (EC_KEY_copy(ret, ec_key) == NULL) {
|
||||
EC_KEY_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int EC_KEY_up_ref(EC_KEY *r)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (CRYPTO_UP_REF(&r->references, &i, r->lock) <= 0)
|
||||
return 0;
|
||||
|
||||
REF_PRINT_COUNT("EC_KEY", r);
|
||||
REF_ASSERT_ISNT(i < 2);
|
||||
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) {
|
||||
ECerr(EC_F_EC_KEY_GENERATE_KEY, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
if (eckey->meth->keygen != NULL)
|
||||
return eckey->meth->keygen(eckey);
|
||||
ECerr(EC_F_EC_KEY_GENERATE_KEY, EC_R_OPERATION_NOT_SUPPORTED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ossl_ec_key_gen(EC_KEY *eckey)
|
||||
{
|
||||
return eckey->group->meth->keygen(eckey);
|
||||
}
|
||||
|
||||
int ec_key_simple_generate_key(EC_KEY *eckey)
|
||||
{
|
||||
int ok = 0;
|
||||
BN_CTX *ctx = NULL;
|
||||
BIGNUM *priv_key = NULL;
|
||||
const BIGNUM *order = NULL;
|
||||
EC_POINT *pub_key = NULL;
|
||||
|
||||
if ((ctx = BN_CTX_new()) == NULL)
|
||||
goto err;
|
||||
|
||||
if (eckey->priv_key == NULL) {
|
||||
priv_key = BN_new();
|
||||
if (priv_key == NULL)
|
||||
goto err;
|
||||
} else
|
||||
priv_key = eckey->priv_key;
|
||||
|
||||
order = EC_GROUP_get0_order(eckey->group);
|
||||
if (order == NULL)
|
||||
goto err;
|
||||
|
||||
do
|
||||
if (!BN_priv_rand_range(priv_key, order))
|
||||
goto err;
|
||||
while (BN_is_zero(priv_key)) ;
|
||||
|
||||
if (eckey->pub_key == NULL) {
|
||||
pub_key = EC_POINT_new(eckey->group);
|
||||
if (pub_key == NULL)
|
||||
goto err;
|
||||
} else
|
||||
pub_key = eckey->pub_key;
|
||||
|
||||
if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, ctx))
|
||||
goto err;
|
||||
|
||||
eckey->priv_key = priv_key;
|
||||
eckey->pub_key = pub_key;
|
||||
|
||||
ok = 1;
|
||||
|
||||
err:
|
||||
if (eckey->pub_key == NULL)
|
||||
EC_POINT_free(pub_key);
|
||||
if (eckey->priv_key != priv_key)
|
||||
BN_free(priv_key);
|
||||
BN_CTX_free(ctx);
|
||||
return ok;
|
||||
}
|
||||
|
||||
int ec_key_simple_generate_public_key(EC_KEY *eckey)
|
||||
{
|
||||
return EC_POINT_mul(eckey->group, eckey->pub_key, eckey->priv_key, NULL,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
int EC_KEY_check_key(const EC_KEY *eckey)
|
||||
{
|
||||
if (eckey == NULL || eckey->group == NULL || eckey->pub_key == NULL) {
|
||||
ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (eckey->group->meth->keycheck == NULL) {
|
||||
ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return eckey->group->meth->keycheck(eckey);
|
||||
}
|
||||
|
||||
int ec_key_simple_check_key(const EC_KEY *eckey)
|
||||
{
|
||||
int ok = 0;
|
||||
BN_CTX *ctx = NULL;
|
||||
const BIGNUM *order = NULL;
|
||||
EC_POINT *point = NULL;
|
||||
|
||||
if (eckey == NULL || eckey->group == NULL || eckey->pub_key == NULL) {
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key)) {
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_POINT_AT_INFINITY);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((ctx = BN_CTX_new()) == NULL)
|
||||
goto err;
|
||||
if ((point = EC_POINT_new(eckey->group)) == NULL)
|
||||
goto err;
|
||||
|
||||
/* testing whether the pub_key is on the elliptic curve */
|
||||
if (EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx) <= 0) {
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_POINT_IS_NOT_ON_CURVE);
|
||||
goto err;
|
||||
}
|
||||
/* testing whether pub_key * order is the point at infinity */
|
||||
order = eckey->group->order;
|
||||
if (BN_is_zero(order)) {
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_INVALID_GROUP_ORDER);
|
||||
goto err;
|
||||
}
|
||||
if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx)) {
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
if (!EC_POINT_is_at_infinity(eckey->group, point)) {
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_WRONG_ORDER);
|
||||
goto err;
|
||||
}
|
||||
/*
|
||||
* in case the priv_key is present : check if generator * priv_key ==
|
||||
* pub_key
|
||||
*/
|
||||
if (eckey->priv_key != NULL) {
|
||||
if (BN_cmp(eckey->priv_key, order) >= 0) {
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_WRONG_ORDER);
|
||||
goto err;
|
||||
}
|
||||
if (!EC_POINT_mul(eckey->group, point, eckey->priv_key,
|
||||
NULL, NULL, ctx)) {
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, ctx) != 0) {
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_INVALID_PRIVATE_KEY);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
ok = 1;
|
||||
err:
|
||||
BN_CTX_free(ctx);
|
||||
EC_POINT_free(point);
|
||||
return ok;
|
||||
}
|
||||
|
||||
int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x,
|
||||
BIGNUM *y)
|
||||
{
|
||||
BN_CTX *ctx = NULL;
|
||||
BIGNUM *tx, *ty;
|
||||
EC_POINT *point = NULL;
|
||||
int ok = 0;
|
||||
|
||||
if (key == NULL || key->group == NULL || x == NULL || y == NULL) {
|
||||
ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES,
|
||||
ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
ctx = BN_CTX_new();
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
point = EC_POINT_new(key->group);
|
||||
|
||||
if (point == NULL)
|
||||
goto err;
|
||||
|
||||
tx = BN_CTX_get(ctx);
|
||||
ty = BN_CTX_get(ctx);
|
||||
if (ty == NULL)
|
||||
goto err;
|
||||
|
||||
if (!EC_POINT_set_affine_coordinates(key->group, point, x, y, ctx))
|
||||
goto err;
|
||||
if (!EC_POINT_get_affine_coordinates(key->group, point, tx, ty, ctx))
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* Check if retrieved coordinates match originals and are less than field
|
||||
* order: if not values are out of range.
|
||||
*/
|
||||
if (BN_cmp(x, tx) || BN_cmp(y, ty)
|
||||
|| (BN_cmp(x, key->group->field) >= 0)
|
||||
|| (BN_cmp(y, key->group->field) >= 0)) {
|
||||
ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES,
|
||||
EC_R_COORDINATES_OUT_OF_RANGE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!EC_KEY_set_public_key(key, point))
|
||||
goto err;
|
||||
|
||||
if (EC_KEY_check_key(key) == 0)
|
||||
goto err;
|
||||
|
||||
ok = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
EC_POINT_free(point);
|
||||
return ok;
|
||||
|
||||
}
|
||||
|
||||
const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key)
|
||||
{
|
||||
return key->group;
|
||||
}
|
||||
|
||||
int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group)
|
||||
{
|
||||
if (key->meth->set_group != NULL && key->meth->set_group(key, group) == 0)
|
||||
return 0;
|
||||
EC_GROUP_free(key->group);
|
||||
key->group = EC_GROUP_dup(group);
|
||||
return (key->group == NULL) ? 0 : 1;
|
||||
}
|
||||
|
||||
const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key)
|
||||
{
|
||||
return key->priv_key;
|
||||
}
|
||||
|
||||
int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key)
|
||||
{
|
||||
if (key->group == NULL || key->group->meth == NULL)
|
||||
return 0;
|
||||
if (key->group->meth->set_private != NULL
|
||||
&& key->group->meth->set_private(key, priv_key) == 0)
|
||||
return 0;
|
||||
if (key->meth->set_private != NULL
|
||||
&& key->meth->set_private(key, priv_key) == 0)
|
||||
return 0;
|
||||
BN_clear_free(key->priv_key);
|
||||
key->priv_key = BN_dup(priv_key);
|
||||
return (key->priv_key == NULL) ? 0 : 1;
|
||||
}
|
||||
|
||||
const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key)
|
||||
{
|
||||
return key->pub_key;
|
||||
}
|
||||
|
||||
int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key)
|
||||
{
|
||||
if (key->meth->set_public != NULL
|
||||
&& key->meth->set_public(key, pub_key) == 0)
|
||||
return 0;
|
||||
EC_POINT_free(key->pub_key);
|
||||
key->pub_key = EC_POINT_dup(pub_key, key->group);
|
||||
return (key->pub_key == NULL) ? 0 : 1;
|
||||
}
|
||||
|
||||
unsigned int EC_KEY_get_enc_flags(const EC_KEY *key)
|
||||
{
|
||||
return key->enc_flag;
|
||||
}
|
||||
|
||||
void EC_KEY_set_enc_flags(EC_KEY *key, unsigned int flags)
|
||||
{
|
||||
key->enc_flag = flags;
|
||||
}
|
||||
|
||||
point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key)
|
||||
{
|
||||
return key->conv_form;
|
||||
}
|
||||
|
||||
void EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform)
|
||||
{
|
||||
key->conv_form = cform;
|
||||
if (key->group != NULL)
|
||||
EC_GROUP_set_point_conversion_form(key->group, cform);
|
||||
}
|
||||
|
||||
void EC_KEY_set_asn1_flag(EC_KEY *key, int flag)
|
||||
{
|
||||
if (key->group != NULL)
|
||||
EC_GROUP_set_asn1_flag(key->group, flag);
|
||||
}
|
||||
|
||||
int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx)
|
||||
{
|
||||
if (key->group == NULL)
|
||||
return 0;
|
||||
return EC_GROUP_precompute_mult(key->group, ctx);
|
||||
}
|
||||
|
||||
int EC_KEY_get_flags(const EC_KEY *key)
|
||||
{
|
||||
return key->flags;
|
||||
}
|
||||
|
||||
void EC_KEY_set_flags(EC_KEY *key, int flags)
|
||||
{
|
||||
key->flags |= flags;
|
||||
}
|
||||
|
||||
void EC_KEY_clear_flags(EC_KEY *key, int flags)
|
||||
{
|
||||
key->flags &= ~flags;
|
||||
}
|
||||
|
||||
size_t EC_KEY_key2buf(const EC_KEY *key, point_conversion_form_t form,
|
||||
unsigned char **pbuf, BN_CTX *ctx)
|
||||
{
|
||||
if (key == NULL || key->pub_key == NULL || key->group == NULL)
|
||||
return 0;
|
||||
return EC_POINT_point2buf(key->group, key->pub_key, form, pbuf, ctx);
|
||||
}
|
||||
|
||||
int EC_KEY_oct2key(EC_KEY *key, const unsigned char *buf, size_t len,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
if (key == NULL || key->group == NULL)
|
||||
return 0;
|
||||
if (key->pub_key == NULL)
|
||||
key->pub_key = EC_POINT_new(key->group);
|
||||
if (key->pub_key == NULL)
|
||||
return 0;
|
||||
if (EC_POINT_oct2point(key->group, key->pub_key, buf, len, ctx) == 0)
|
||||
return 0;
|
||||
/*
|
||||
* Save the point conversion form.
|
||||
* For non-custom curves the first octet of the buffer (excluding
|
||||
* the last significant bit) contains the point conversion form.
|
||||
* EC_POINT_oct2point() has already performed sanity checking of
|
||||
* the buffer so we know it is valid.
|
||||
*/
|
||||
if ((key->group->meth->flags & EC_FLAGS_CUSTOM_CURVE) == 0)
|
||||
key->conv_form = (point_conversion_form_t)(buf[0] & ~0x01);
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t EC_KEY_priv2oct(const EC_KEY *eckey,
|
||||
unsigned char *buf, size_t len)
|
||||
{
|
||||
if (eckey->group == NULL || eckey->group->meth == NULL)
|
||||
return 0;
|
||||
if (eckey->group->meth->priv2oct == NULL) {
|
||||
ECerr(EC_F_EC_KEY_PRIV2OCT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return eckey->group->meth->priv2oct(eckey, buf, len);
|
||||
}
|
||||
|
||||
size_t ec_key_simple_priv2oct(const EC_KEY *eckey,
|
||||
unsigned char *buf, size_t len)
|
||||
{
|
||||
size_t buf_len;
|
||||
|
||||
buf_len = (EC_GROUP_order_bits(eckey->group) + 7) / 8;
|
||||
if (eckey->priv_key == NULL)
|
||||
return 0;
|
||||
if (buf == NULL)
|
||||
return buf_len;
|
||||
else if (len < buf_len)
|
||||
return 0;
|
||||
|
||||
/* Octetstring may need leading zeros if BN is to short */
|
||||
|
||||
if (BN_bn2binpad(eckey->priv_key, buf, buf_len) == -1) {
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_PRIV2OCT, EC_R_BUFFER_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return buf_len;
|
||||
}
|
||||
|
||||
int EC_KEY_oct2priv(EC_KEY *eckey, const unsigned char *buf, size_t len)
|
||||
{
|
||||
if (eckey->group == NULL || eckey->group->meth == NULL)
|
||||
return 0;
|
||||
if (eckey->group->meth->oct2priv == NULL) {
|
||||
ECerr(EC_F_EC_KEY_OCT2PRIV, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
||||
return 0;
|
||||
}
|
||||
return eckey->group->meth->oct2priv(eckey, buf, len);
|
||||
}
|
||||
|
||||
int ec_key_simple_oct2priv(EC_KEY *eckey, const unsigned char *buf, size_t len)
|
||||
{
|
||||
if (eckey->priv_key == NULL)
|
||||
eckey->priv_key = BN_secure_new();
|
||||
if (eckey->priv_key == NULL) {
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_OCT2PRIV, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
eckey->priv_key = BN_bin2bn(buf, len, eckey->priv_key);
|
||||
if (eckey->priv_key == NULL) {
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_OCT2PRIV, ERR_R_BN_LIB);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t EC_KEY_priv2buf(const EC_KEY *eckey, unsigned char **pbuf)
|
||||
{
|
||||
size_t len;
|
||||
unsigned char *buf;
|
||||
|
||||
len = EC_KEY_priv2oct(eckey, NULL, 0);
|
||||
if (len == 0)
|
||||
return 0;
|
||||
if ((buf = OPENSSL_malloc(len)) == NULL) {
|
||||
ECerr(EC_F_EC_KEY_PRIV2BUF, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
len = EC_KEY_priv2oct(eckey, buf, len);
|
||||
if (len == 0) {
|
||||
OPENSSL_free(buf);
|
||||
return 0;
|
||||
}
|
||||
*pbuf = buf;
|
||||
return len;
|
||||
}
|
||||
|
||||
int EC_KEY_can_sign(const EC_KEY *eckey)
|
||||
{
|
||||
if (eckey->group == NULL || eckey->group->meth == NULL
|
||||
|| (eckey->group->meth->flags & EC_FLAGS_NO_SIGN))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
317
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ec_kmeth.c
vendored
Normal file
317
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ec_kmeth.c
vendored
Normal file
|
@ -0,0 +1,317 @@
|
|||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/engine.h>
|
||||
#include <openssl/err.h>
|
||||
#include "ec_lcl.h"
|
||||
|
||||
|
||||
static const EC_KEY_METHOD openssl_ec_key_method = {
|
||||
"OpenSSL EC_KEY method",
|
||||
0,
|
||||
0,0,0,0,0,0,
|
||||
ossl_ec_key_gen,
|
||||
ossl_ecdh_compute_key,
|
||||
ossl_ecdsa_sign,
|
||||
ossl_ecdsa_sign_setup,
|
||||
ossl_ecdsa_sign_sig,
|
||||
ossl_ecdsa_verify,
|
||||
ossl_ecdsa_verify_sig
|
||||
};
|
||||
|
||||
static const EC_KEY_METHOD *default_ec_key_meth = &openssl_ec_key_method;
|
||||
|
||||
const EC_KEY_METHOD *EC_KEY_OpenSSL(void)
|
||||
{
|
||||
return &openssl_ec_key_method;
|
||||
}
|
||||
|
||||
const EC_KEY_METHOD *EC_KEY_get_default_method(void)
|
||||
{
|
||||
return default_ec_key_meth;
|
||||
}
|
||||
|
||||
void EC_KEY_set_default_method(const EC_KEY_METHOD *meth)
|
||||
{
|
||||
if (meth == NULL)
|
||||
default_ec_key_meth = &openssl_ec_key_method;
|
||||
else
|
||||
default_ec_key_meth = meth;
|
||||
}
|
||||
|
||||
const EC_KEY_METHOD *EC_KEY_get_method(const EC_KEY *key)
|
||||
{
|
||||
return key->meth;
|
||||
}
|
||||
|
||||
int EC_KEY_set_method(EC_KEY *key, const EC_KEY_METHOD *meth)
|
||||
{
|
||||
void (*finish)(EC_KEY *key) = key->meth->finish;
|
||||
|
||||
if (finish != NULL)
|
||||
finish(key);
|
||||
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
ENGINE_finish(key->engine);
|
||||
key->engine = NULL;
|
||||
#endif
|
||||
|
||||
key->meth = meth;
|
||||
if (meth->init != NULL)
|
||||
return meth->init(key);
|
||||
return 1;
|
||||
}
|
||||
|
||||
EC_KEY *EC_KEY_new_method(ENGINE *engine)
|
||||
{
|
||||
EC_KEY *ret = OPENSSL_zalloc(sizeof(*ret));
|
||||
|
||||
if (ret == NULL) {
|
||||
ECerr(EC_F_EC_KEY_NEW_METHOD, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret->references = 1;
|
||||
ret->lock = CRYPTO_THREAD_lock_new();
|
||||
if (ret->lock == NULL) {
|
||||
ECerr(EC_F_EC_KEY_NEW_METHOD, ERR_R_MALLOC_FAILURE);
|
||||
OPENSSL_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret->meth = EC_KEY_get_default_method();
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
if (engine != NULL) {
|
||||
if (!ENGINE_init(engine)) {
|
||||
ECerr(EC_F_EC_KEY_NEW_METHOD, ERR_R_ENGINE_LIB);
|
||||
goto err;
|
||||
}
|
||||
ret->engine = engine;
|
||||
} else
|
||||
ret->engine = ENGINE_get_default_EC();
|
||||
if (ret->engine != NULL) {
|
||||
ret->meth = ENGINE_get_EC(ret->engine);
|
||||
if (ret->meth == NULL) {
|
||||
ECerr(EC_F_EC_KEY_NEW_METHOD, ERR_R_ENGINE_LIB);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ret->version = 1;
|
||||
ret->conv_form = POINT_CONVERSION_UNCOMPRESSED;
|
||||
|
||||
if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_EC_KEY, ret, &ret->ex_data)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (ret->meth->init != NULL && ret->meth->init(ret) == 0) {
|
||||
ECerr(EC_F_EC_KEY_NEW_METHOD, ERR_R_INIT_FAIL);
|
||||
goto err;
|
||||
}
|
||||
return ret;
|
||||
|
||||
err:
|
||||
EC_KEY_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
|
||||
const EC_KEY *eckey,
|
||||
void *(*KDF) (const void *in, size_t inlen, void *out,
|
||||
size_t *outlen))
|
||||
{
|
||||
unsigned char *sec = NULL;
|
||||
size_t seclen;
|
||||
if (eckey->meth->compute_key == NULL) {
|
||||
ECerr(EC_F_ECDH_COMPUTE_KEY, EC_R_OPERATION_NOT_SUPPORTED);
|
||||
return 0;
|
||||
}
|
||||
if (outlen > INT_MAX) {
|
||||
ECerr(EC_F_ECDH_COMPUTE_KEY, EC_R_INVALID_OUTPUT_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
if (!eckey->meth->compute_key(&sec, &seclen, pub_key, eckey))
|
||||
return 0;
|
||||
if (KDF != NULL) {
|
||||
KDF(sec, seclen, out, &outlen);
|
||||
} else {
|
||||
if (outlen > seclen)
|
||||
outlen = seclen;
|
||||
memcpy(out, sec, outlen);
|
||||
}
|
||||
OPENSSL_clear_free(sec, seclen);
|
||||
return outlen;
|
||||
}
|
||||
|
||||
EC_KEY_METHOD *EC_KEY_METHOD_new(const EC_KEY_METHOD *meth)
|
||||
{
|
||||
EC_KEY_METHOD *ret = OPENSSL_zalloc(sizeof(*meth));
|
||||
|
||||
if (ret == NULL)
|
||||
return NULL;
|
||||
if (meth != NULL)
|
||||
*ret = *meth;
|
||||
ret->flags |= EC_KEY_METHOD_DYNAMIC;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void EC_KEY_METHOD_free(EC_KEY_METHOD *meth)
|
||||
{
|
||||
if (meth->flags & EC_KEY_METHOD_DYNAMIC)
|
||||
OPENSSL_free(meth);
|
||||
}
|
||||
|
||||
void EC_KEY_METHOD_set_init(EC_KEY_METHOD *meth,
|
||||
int (*init)(EC_KEY *key),
|
||||
void (*finish)(EC_KEY *key),
|
||||
int (*copy)(EC_KEY *dest, const EC_KEY *src),
|
||||
int (*set_group)(EC_KEY *key, const EC_GROUP *grp),
|
||||
int (*set_private)(EC_KEY *key,
|
||||
const BIGNUM *priv_key),
|
||||
int (*set_public)(EC_KEY *key,
|
||||
const EC_POINT *pub_key))
|
||||
{
|
||||
meth->init = init;
|
||||
meth->finish = finish;
|
||||
meth->copy = copy;
|
||||
meth->set_group = set_group;
|
||||
meth->set_private = set_private;
|
||||
meth->set_public = set_public;
|
||||
}
|
||||
|
||||
void EC_KEY_METHOD_set_keygen(EC_KEY_METHOD *meth,
|
||||
int (*keygen)(EC_KEY *key))
|
||||
{
|
||||
meth->keygen = keygen;
|
||||
}
|
||||
|
||||
void EC_KEY_METHOD_set_compute_key(EC_KEY_METHOD *meth,
|
||||
int (*ckey)(unsigned char **psec,
|
||||
size_t *pseclen,
|
||||
const EC_POINT *pub_key,
|
||||
const EC_KEY *ecdh))
|
||||
{
|
||||
meth->compute_key = ckey;
|
||||
}
|
||||
|
||||
void EC_KEY_METHOD_set_sign(EC_KEY_METHOD *meth,
|
||||
int (*sign)(int type, const unsigned char *dgst,
|
||||
int dlen, unsigned char *sig,
|
||||
unsigned int *siglen,
|
||||
const BIGNUM *kinv, const BIGNUM *r,
|
||||
EC_KEY *eckey),
|
||||
int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in,
|
||||
BIGNUM **kinvp, BIGNUM **rp),
|
||||
ECDSA_SIG *(*sign_sig)(const unsigned char *dgst,
|
||||
int dgst_len,
|
||||
const BIGNUM *in_kinv,
|
||||
const BIGNUM *in_r,
|
||||
EC_KEY *eckey))
|
||||
{
|
||||
meth->sign = sign;
|
||||
meth->sign_setup = sign_setup;
|
||||
meth->sign_sig = sign_sig;
|
||||
}
|
||||
|
||||
void EC_KEY_METHOD_set_verify(EC_KEY_METHOD *meth,
|
||||
int (*verify)(int type, const unsigned
|
||||
char *dgst, int dgst_len,
|
||||
const unsigned char *sigbuf,
|
||||
int sig_len, EC_KEY *eckey),
|
||||
int (*verify_sig)(const unsigned char *dgst,
|
||||
int dgst_len,
|
||||
const ECDSA_SIG *sig,
|
||||
EC_KEY *eckey))
|
||||
{
|
||||
meth->verify = verify;
|
||||
meth->verify_sig = verify_sig;
|
||||
}
|
||||
|
||||
void EC_KEY_METHOD_get_init(const EC_KEY_METHOD *meth,
|
||||
int (**pinit)(EC_KEY *key),
|
||||
void (**pfinish)(EC_KEY *key),
|
||||
int (**pcopy)(EC_KEY *dest, const EC_KEY *src),
|
||||
int (**pset_group)(EC_KEY *key,
|
||||
const EC_GROUP *grp),
|
||||
int (**pset_private)(EC_KEY *key,
|
||||
const BIGNUM *priv_key),
|
||||
int (**pset_public)(EC_KEY *key,
|
||||
const EC_POINT *pub_key))
|
||||
{
|
||||
if (pinit != NULL)
|
||||
*pinit = meth->init;
|
||||
if (pfinish != NULL)
|
||||
*pfinish = meth->finish;
|
||||
if (pcopy != NULL)
|
||||
*pcopy = meth->copy;
|
||||
if (pset_group != NULL)
|
||||
*pset_group = meth->set_group;
|
||||
if (pset_private != NULL)
|
||||
*pset_private = meth->set_private;
|
||||
if (pset_public != NULL)
|
||||
*pset_public = meth->set_public;
|
||||
}
|
||||
|
||||
void EC_KEY_METHOD_get_keygen(const EC_KEY_METHOD *meth,
|
||||
int (**pkeygen)(EC_KEY *key))
|
||||
{
|
||||
if (pkeygen != NULL)
|
||||
*pkeygen = meth->keygen;
|
||||
}
|
||||
|
||||
void EC_KEY_METHOD_get_compute_key(const EC_KEY_METHOD *meth,
|
||||
int (**pck)(unsigned char **pout,
|
||||
size_t *poutlen,
|
||||
const EC_POINT *pub_key,
|
||||
const EC_KEY *ecdh))
|
||||
{
|
||||
if (pck != NULL)
|
||||
*pck = meth->compute_key;
|
||||
}
|
||||
|
||||
void EC_KEY_METHOD_get_sign(const EC_KEY_METHOD *meth,
|
||||
int (**psign)(int type, const unsigned char *dgst,
|
||||
int dlen, unsigned char *sig,
|
||||
unsigned int *siglen,
|
||||
const BIGNUM *kinv, const BIGNUM *r,
|
||||
EC_KEY *eckey),
|
||||
int (**psign_setup)(EC_KEY *eckey, BN_CTX *ctx_in,
|
||||
BIGNUM **kinvp, BIGNUM **rp),
|
||||
ECDSA_SIG *(**psign_sig)(const unsigned char *dgst,
|
||||
int dgst_len,
|
||||
const BIGNUM *in_kinv,
|
||||
const BIGNUM *in_r,
|
||||
EC_KEY *eckey))
|
||||
{
|
||||
if (psign != NULL)
|
||||
*psign = meth->sign;
|
||||
if (psign_setup != NULL)
|
||||
*psign_setup = meth->sign_setup;
|
||||
if (psign_sig != NULL)
|
||||
*psign_sig = meth->sign_sig;
|
||||
}
|
||||
|
||||
void EC_KEY_METHOD_get_verify(const EC_KEY_METHOD *meth,
|
||||
int (**pverify)(int type, const unsigned
|
||||
char *dgst, int dgst_len,
|
||||
const unsigned char *sigbuf,
|
||||
int sig_len, EC_KEY *eckey),
|
||||
int (**pverify_sig)(const unsigned char *dgst,
|
||||
int dgst_len,
|
||||
const ECDSA_SIG *sig,
|
||||
EC_KEY *eckey))
|
||||
{
|
||||
if (pverify != NULL)
|
||||
*pverify = meth->verify;
|
||||
if (pverify_sig != NULL)
|
||||
*pverify_sig = meth->verify_sig;
|
||||
}
|
737
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ec_lcl.h
vendored
Normal file
737
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ec_lcl.h
vendored
Normal file
|
@ -0,0 +1,737 @@
|
|||
/*
|
||||
* Copyright 2001-2019 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <openssl/obj_mac.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/bn.h>
|
||||
#include "internal/refcount.h"
|
||||
#include "internal/ec_int.h"
|
||||
|
||||
#if defined(__SUNPRO_C)
|
||||
# if __SUNPRO_C >= 0x520
|
||||
# pragma error_messages (off,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Use default functions for poin2oct, oct2point and compressed coordinates */
|
||||
#define EC_FLAGS_DEFAULT_OCT 0x1
|
||||
|
||||
/* Use custom formats for EC_GROUP, EC_POINT and EC_KEY */
|
||||
#define EC_FLAGS_CUSTOM_CURVE 0x2
|
||||
|
||||
/* Curve does not support signing operations */
|
||||
#define EC_FLAGS_NO_SIGN 0x4
|
||||
|
||||
/*
|
||||
* Structure details are not part of the exported interface, so all this may
|
||||
* change in future versions.
|
||||
*/
|
||||
|
||||
struct ec_method_st {
|
||||
/* Various method flags */
|
||||
int flags;
|
||||
/* used by EC_METHOD_get_field_type: */
|
||||
int field_type; /* a NID */
|
||||
/*
|
||||
* used by EC_GROUP_new, EC_GROUP_free, EC_GROUP_clear_free,
|
||||
* EC_GROUP_copy:
|
||||
*/
|
||||
int (*group_init) (EC_GROUP *);
|
||||
void (*group_finish) (EC_GROUP *);
|
||||
void (*group_clear_finish) (EC_GROUP *);
|
||||
int (*group_copy) (EC_GROUP *, const EC_GROUP *);
|
||||
/* used by EC_GROUP_set_curve, EC_GROUP_get_curve: */
|
||||
int (*group_set_curve) (EC_GROUP *, const BIGNUM *p, const BIGNUM *a,
|
||||
const BIGNUM *b, BN_CTX *);
|
||||
int (*group_get_curve) (const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b,
|
||||
BN_CTX *);
|
||||
/* used by EC_GROUP_get_degree: */
|
||||
int (*group_get_degree) (const EC_GROUP *);
|
||||
int (*group_order_bits) (const EC_GROUP *);
|
||||
/* used by EC_GROUP_check: */
|
||||
int (*group_check_discriminant) (const EC_GROUP *, BN_CTX *);
|
||||
/*
|
||||
* used by EC_POINT_new, EC_POINT_free, EC_POINT_clear_free,
|
||||
* EC_POINT_copy:
|
||||
*/
|
||||
int (*point_init) (EC_POINT *);
|
||||
void (*point_finish) (EC_POINT *);
|
||||
void (*point_clear_finish) (EC_POINT *);
|
||||
int (*point_copy) (EC_POINT *, const EC_POINT *);
|
||||
/*-
|
||||
* used by EC_POINT_set_to_infinity,
|
||||
* EC_POINT_set_Jprojective_coordinates_GFp,
|
||||
* EC_POINT_get_Jprojective_coordinates_GFp,
|
||||
* EC_POINT_set_affine_coordinates,
|
||||
* EC_POINT_get_affine_coordinates,
|
||||
* EC_POINT_set_compressed_coordinates:
|
||||
*/
|
||||
int (*point_set_to_infinity) (const EC_GROUP *, EC_POINT *);
|
||||
int (*point_set_Jprojective_coordinates_GFp) (const EC_GROUP *,
|
||||
EC_POINT *, const BIGNUM *x,
|
||||
const BIGNUM *y,
|
||||
const BIGNUM *z, BN_CTX *);
|
||||
int (*point_get_Jprojective_coordinates_GFp) (const EC_GROUP *,
|
||||
const EC_POINT *, BIGNUM *x,
|
||||
BIGNUM *y, BIGNUM *z,
|
||||
BN_CTX *);
|
||||
int (*point_set_affine_coordinates) (const EC_GROUP *, EC_POINT *,
|
||||
const BIGNUM *x, const BIGNUM *y,
|
||||
BN_CTX *);
|
||||
int (*point_get_affine_coordinates) (const EC_GROUP *, const EC_POINT *,
|
||||
BIGNUM *x, BIGNUM *y, BN_CTX *);
|
||||
int (*point_set_compressed_coordinates) (const EC_GROUP *, EC_POINT *,
|
||||
const BIGNUM *x, int y_bit,
|
||||
BN_CTX *);
|
||||
/* used by EC_POINT_point2oct, EC_POINT_oct2point: */
|
||||
size_t (*point2oct) (const EC_GROUP *, const EC_POINT *,
|
||||
point_conversion_form_t form, unsigned char *buf,
|
||||
size_t len, BN_CTX *);
|
||||
int (*oct2point) (const EC_GROUP *, EC_POINT *, const unsigned char *buf,
|
||||
size_t len, BN_CTX *);
|
||||
/* used by EC_POINT_add, EC_POINT_dbl, ECP_POINT_invert: */
|
||||
int (*add) (const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
|
||||
const EC_POINT *b, BN_CTX *);
|
||||
int (*dbl) (const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
|
||||
int (*invert) (const EC_GROUP *, EC_POINT *, BN_CTX *);
|
||||
/*
|
||||
* used by EC_POINT_is_at_infinity, EC_POINT_is_on_curve, EC_POINT_cmp:
|
||||
*/
|
||||
int (*is_at_infinity) (const EC_GROUP *, const EC_POINT *);
|
||||
int (*is_on_curve) (const EC_GROUP *, const EC_POINT *, BN_CTX *);
|
||||
int (*point_cmp) (const EC_GROUP *, const EC_POINT *a, const EC_POINT *b,
|
||||
BN_CTX *);
|
||||
/* used by EC_POINT_make_affine, EC_POINTs_make_affine: */
|
||||
int (*make_affine) (const EC_GROUP *, EC_POINT *, BN_CTX *);
|
||||
int (*points_make_affine) (const EC_GROUP *, size_t num, EC_POINT *[],
|
||||
BN_CTX *);
|
||||
/*
|
||||
* used by EC_POINTs_mul, EC_POINT_mul, EC_POINT_precompute_mult,
|
||||
* EC_POINT_have_precompute_mult (default implementations are used if the
|
||||
* 'mul' pointer is 0):
|
||||
*/
|
||||
/*-
|
||||
* mul() calculates the value
|
||||
*
|
||||
* r := generator * scalar
|
||||
* + points[0] * scalars[0]
|
||||
* + ...
|
||||
* + points[num-1] * scalars[num-1].
|
||||
*
|
||||
* For a fixed point multiplication (scalar != NULL, num == 0)
|
||||
* or a variable point multiplication (scalar == NULL, num == 1),
|
||||
* mul() must use a constant time algorithm: in both cases callers
|
||||
* should provide an input scalar (either scalar or scalars[0])
|
||||
* in the range [0, ec_group_order); for robustness, implementers
|
||||
* should handle the case when the scalar has not been reduced, but
|
||||
* may treat it as an unusual input, without any constant-timeness
|
||||
* guarantee.
|
||||
*/
|
||||
int (*mul) (const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
||||
size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
|
||||
BN_CTX *);
|
||||
int (*precompute_mult) (EC_GROUP *group, BN_CTX *);
|
||||
int (*have_precompute_mult) (const EC_GROUP *group);
|
||||
/* internal functions */
|
||||
/*
|
||||
* 'field_mul', 'field_sqr', and 'field_div' can be used by 'add' and
|
||||
* 'dbl' so that the same implementations of point operations can be used
|
||||
* with different optimized implementations of expensive field
|
||||
* operations:
|
||||
*/
|
||||
int (*field_mul) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
|
||||
const BIGNUM *b, BN_CTX *);
|
||||
int (*field_sqr) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
|
||||
int (*field_div) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
|
||||
const BIGNUM *b, BN_CTX *);
|
||||
/*-
|
||||
* 'field_inv' computes the multipicative inverse of a in the field,
|
||||
* storing the result in r.
|
||||
*
|
||||
* If 'a' is zero (or equivalent), you'll get an EC_R_CANNOT_INVERT error.
|
||||
*/
|
||||
int (*field_inv) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
|
||||
/* e.g. to Montgomery */
|
||||
int (*field_encode) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
|
||||
BN_CTX *);
|
||||
/* e.g. from Montgomery */
|
||||
int (*field_decode) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
|
||||
BN_CTX *);
|
||||
int (*field_set_to_one) (const EC_GROUP *, BIGNUM *r, BN_CTX *);
|
||||
/* private key operations */
|
||||
size_t (*priv2oct)(const EC_KEY *eckey, unsigned char *buf, size_t len);
|
||||
int (*oct2priv)(EC_KEY *eckey, const unsigned char *buf, size_t len);
|
||||
int (*set_private)(EC_KEY *eckey, const BIGNUM *priv_key);
|
||||
int (*keygen)(EC_KEY *eckey);
|
||||
int (*keycheck)(const EC_KEY *eckey);
|
||||
int (*keygenpub)(EC_KEY *eckey);
|
||||
int (*keycopy)(EC_KEY *dst, const EC_KEY *src);
|
||||
void (*keyfinish)(EC_KEY *eckey);
|
||||
/* custom ECDH operation */
|
||||
int (*ecdh_compute_key)(unsigned char **pout, size_t *poutlen,
|
||||
const EC_POINT *pub_key, const EC_KEY *ecdh);
|
||||
/* Inverse modulo order */
|
||||
int (*field_inverse_mod_ord)(const EC_GROUP *, BIGNUM *r,
|
||||
const BIGNUM *x, BN_CTX *);
|
||||
int (*blind_coordinates)(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx);
|
||||
int (*ladder_pre)(const EC_GROUP *group,
|
||||
EC_POINT *r, EC_POINT *s,
|
||||
EC_POINT *p, BN_CTX *ctx);
|
||||
int (*ladder_step)(const EC_GROUP *group,
|
||||
EC_POINT *r, EC_POINT *s,
|
||||
EC_POINT *p, BN_CTX *ctx);
|
||||
int (*ladder_post)(const EC_GROUP *group,
|
||||
EC_POINT *r, EC_POINT *s,
|
||||
EC_POINT *p, BN_CTX *ctx);
|
||||
};
|
||||
|
||||
/*
|
||||
* Types and functions to manipulate pre-computed values.
|
||||
*/
|
||||
typedef struct nistp224_pre_comp_st NISTP224_PRE_COMP;
|
||||
typedef struct nistp256_pre_comp_st NISTP256_PRE_COMP;
|
||||
typedef struct nistp521_pre_comp_st NISTP521_PRE_COMP;
|
||||
typedef struct nistz256_pre_comp_st NISTZ256_PRE_COMP;
|
||||
typedef struct ec_pre_comp_st EC_PRE_COMP;
|
||||
|
||||
struct ec_group_st {
|
||||
const EC_METHOD *meth;
|
||||
EC_POINT *generator; /* optional */
|
||||
BIGNUM *order, *cofactor;
|
||||
int curve_name; /* optional NID for named curve */
|
||||
int asn1_flag; /* flag to control the asn1 encoding */
|
||||
point_conversion_form_t asn1_form;
|
||||
unsigned char *seed; /* optional seed for parameters (appears in
|
||||
* ASN1) */
|
||||
size_t seed_len;
|
||||
/*
|
||||
* The following members are handled by the method functions, even if
|
||||
* they appear generic
|
||||
*/
|
||||
/*
|
||||
* Field specification. For curves over GF(p), this is the modulus; for
|
||||
* curves over GF(2^m), this is the irreducible polynomial defining the
|
||||
* field.
|
||||
*/
|
||||
BIGNUM *field;
|
||||
/*
|
||||
* Field specification for curves over GF(2^m). The irreducible f(t) is
|
||||
* then of the form: t^poly[0] + t^poly[1] + ... + t^poly[k] where m =
|
||||
* poly[0] > poly[1] > ... > poly[k] = 0. The array is terminated with
|
||||
* poly[k+1]=-1. All elliptic curve irreducibles have at most 5 non-zero
|
||||
* terms.
|
||||
*/
|
||||
int poly[6];
|
||||
/*
|
||||
* Curve coefficients. (Here the assumption is that BIGNUMs can be used
|
||||
* or abused for all kinds of fields, not just GF(p).) For characteristic
|
||||
* > 3, the curve is defined by a Weierstrass equation of the form y^2 =
|
||||
* x^3 + a*x + b. For characteristic 2, the curve is defined by an
|
||||
* equation of the form y^2 + x*y = x^3 + a*x^2 + b.
|
||||
*/
|
||||
BIGNUM *a, *b;
|
||||
/* enable optimized point arithmetics for special case */
|
||||
int a_is_minus3;
|
||||
/* method-specific (e.g., Montgomery structure) */
|
||||
void *field_data1;
|
||||
/* method-specific */
|
||||
void *field_data2;
|
||||
/* method-specific */
|
||||
int (*field_mod_func) (BIGNUM *, const BIGNUM *, const BIGNUM *,
|
||||
BN_CTX *);
|
||||
/* data for ECDSA inverse */
|
||||
BN_MONT_CTX *mont_data;
|
||||
|
||||
/*
|
||||
* Precomputed values for speed. The PCT_xxx names match the
|
||||
* pre_comp.xxx union names; see the SETPRECOMP and HAVEPRECOMP
|
||||
* macros, below.
|
||||
*/
|
||||
enum {
|
||||
PCT_none,
|
||||
PCT_nistp224, PCT_nistp256, PCT_nistp521, PCT_nistz256,
|
||||
PCT_ec
|
||||
} pre_comp_type;
|
||||
union {
|
||||
NISTP224_PRE_COMP *nistp224;
|
||||
NISTP256_PRE_COMP *nistp256;
|
||||
NISTP521_PRE_COMP *nistp521;
|
||||
NISTZ256_PRE_COMP *nistz256;
|
||||
EC_PRE_COMP *ec;
|
||||
} pre_comp;
|
||||
};
|
||||
|
||||
#define SETPRECOMP(g, type, pre) \
|
||||
g->pre_comp_type = PCT_##type, g->pre_comp.type = pre
|
||||
#define HAVEPRECOMP(g, type) \
|
||||
g->pre_comp_type == PCT_##type && g->pre_comp.type != NULL
|
||||
|
||||
struct ec_key_st {
|
||||
const EC_KEY_METHOD *meth;
|
||||
ENGINE *engine;
|
||||
int version;
|
||||
EC_GROUP *group;
|
||||
EC_POINT *pub_key;
|
||||
BIGNUM *priv_key;
|
||||
unsigned int enc_flag;
|
||||
point_conversion_form_t conv_form;
|
||||
CRYPTO_REF_COUNT references;
|
||||
int flags;
|
||||
CRYPTO_EX_DATA ex_data;
|
||||
CRYPTO_RWLOCK *lock;
|
||||
};
|
||||
|
||||
struct ec_point_st {
|
||||
const EC_METHOD *meth;
|
||||
/* NID for the curve if known */
|
||||
int curve_name;
|
||||
/*
|
||||
* All members except 'meth' are handled by the method functions, even if
|
||||
* they appear generic
|
||||
*/
|
||||
BIGNUM *X;
|
||||
BIGNUM *Y;
|
||||
BIGNUM *Z; /* Jacobian projective coordinates: * (X, Y,
|
||||
* Z) represents (X/Z^2, Y/Z^3) if Z != 0 */
|
||||
int Z_is_one; /* enable optimized point arithmetics for
|
||||
* special case */
|
||||
};
|
||||
|
||||
static ossl_inline int ec_point_is_compat(const EC_POINT *point,
|
||||
const EC_GROUP *group)
|
||||
{
|
||||
if (group->meth != point->meth
|
||||
|| (group->curve_name != 0
|
||||
&& point->curve_name != 0
|
||||
&& group->curve_name != point->curve_name))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
NISTP224_PRE_COMP *EC_nistp224_pre_comp_dup(NISTP224_PRE_COMP *);
|
||||
NISTP256_PRE_COMP *EC_nistp256_pre_comp_dup(NISTP256_PRE_COMP *);
|
||||
NISTP521_PRE_COMP *EC_nistp521_pre_comp_dup(NISTP521_PRE_COMP *);
|
||||
NISTZ256_PRE_COMP *EC_nistz256_pre_comp_dup(NISTZ256_PRE_COMP *);
|
||||
NISTP256_PRE_COMP *EC_nistp256_pre_comp_dup(NISTP256_PRE_COMP *);
|
||||
EC_PRE_COMP *EC_ec_pre_comp_dup(EC_PRE_COMP *);
|
||||
|
||||
void EC_pre_comp_free(EC_GROUP *group);
|
||||
void EC_nistp224_pre_comp_free(NISTP224_PRE_COMP *);
|
||||
void EC_nistp256_pre_comp_free(NISTP256_PRE_COMP *);
|
||||
void EC_nistp521_pre_comp_free(NISTP521_PRE_COMP *);
|
||||
void EC_nistz256_pre_comp_free(NISTZ256_PRE_COMP *);
|
||||
void EC_ec_pre_comp_free(EC_PRE_COMP *);
|
||||
|
||||
/*
|
||||
* method functions in ec_mult.c (ec_lib.c uses these as defaults if
|
||||
* group->method->mul is 0)
|
||||
*/
|
||||
int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
||||
size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
|
||||
BN_CTX *);
|
||||
int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *);
|
||||
int ec_wNAF_have_precompute_mult(const EC_GROUP *group);
|
||||
|
||||
/* method functions in ecp_smpl.c */
|
||||
int ec_GFp_simple_group_init(EC_GROUP *);
|
||||
void ec_GFp_simple_group_finish(EC_GROUP *);
|
||||
void ec_GFp_simple_group_clear_finish(EC_GROUP *);
|
||||
int ec_GFp_simple_group_copy(EC_GROUP *, const EC_GROUP *);
|
||||
int ec_GFp_simple_group_set_curve(EC_GROUP *, const BIGNUM *p,
|
||||
const BIGNUM *a, const BIGNUM *b, BN_CTX *);
|
||||
int ec_GFp_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a,
|
||||
BIGNUM *b, BN_CTX *);
|
||||
int ec_GFp_simple_group_get_degree(const EC_GROUP *);
|
||||
int ec_GFp_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *);
|
||||
int ec_GFp_simple_point_init(EC_POINT *);
|
||||
void ec_GFp_simple_point_finish(EC_POINT *);
|
||||
void ec_GFp_simple_point_clear_finish(EC_POINT *);
|
||||
int ec_GFp_simple_point_copy(EC_POINT *, const EC_POINT *);
|
||||
int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *);
|
||||
int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *,
|
||||
EC_POINT *, const BIGNUM *x,
|
||||
const BIGNUM *y,
|
||||
const BIGNUM *z, BN_CTX *);
|
||||
int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *,
|
||||
const EC_POINT *, BIGNUM *x,
|
||||
BIGNUM *y, BIGNUM *z,
|
||||
BN_CTX *);
|
||||
int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *,
|
||||
const BIGNUM *x,
|
||||
const BIGNUM *y, BN_CTX *);
|
||||
int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *,
|
||||
const EC_POINT *, BIGNUM *x,
|
||||
BIGNUM *y, BN_CTX *);
|
||||
int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *,
|
||||
const BIGNUM *x, int y_bit,
|
||||
BN_CTX *);
|
||||
size_t ec_GFp_simple_point2oct(const EC_GROUP *, const EC_POINT *,
|
||||
point_conversion_form_t form,
|
||||
unsigned char *buf, size_t len, BN_CTX *);
|
||||
int ec_GFp_simple_oct2point(const EC_GROUP *, EC_POINT *,
|
||||
const unsigned char *buf, size_t len, BN_CTX *);
|
||||
int ec_GFp_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
|
||||
const EC_POINT *b, BN_CTX *);
|
||||
int ec_GFp_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
|
||||
BN_CTX *);
|
||||
int ec_GFp_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *);
|
||||
int ec_GFp_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *);
|
||||
int ec_GFp_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *);
|
||||
int ec_GFp_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b,
|
||||
BN_CTX *);
|
||||
int ec_GFp_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
|
||||
int ec_GFp_simple_points_make_affine(const EC_GROUP *, size_t num,
|
||||
EC_POINT *[], BN_CTX *);
|
||||
int ec_GFp_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
|
||||
const BIGNUM *b, BN_CTX *);
|
||||
int ec_GFp_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
|
||||
BN_CTX *);
|
||||
int ec_GFp_simple_field_inv(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
|
||||
BN_CTX *);
|
||||
int ec_GFp_simple_blind_coordinates(const EC_GROUP *group, EC_POINT *p,
|
||||
BN_CTX *ctx);
|
||||
int ec_GFp_simple_ladder_pre(const EC_GROUP *group,
|
||||
EC_POINT *r, EC_POINT *s,
|
||||
EC_POINT *p, BN_CTX *ctx);
|
||||
int ec_GFp_simple_ladder_step(const EC_GROUP *group,
|
||||
EC_POINT *r, EC_POINT *s,
|
||||
EC_POINT *p, BN_CTX *ctx);
|
||||
int ec_GFp_simple_ladder_post(const EC_GROUP *group,
|
||||
EC_POINT *r, EC_POINT *s,
|
||||
EC_POINT *p, BN_CTX *ctx);
|
||||
|
||||
/* method functions in ecp_mont.c */
|
||||
int ec_GFp_mont_group_init(EC_GROUP *);
|
||||
int ec_GFp_mont_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a,
|
||||
const BIGNUM *b, BN_CTX *);
|
||||
void ec_GFp_mont_group_finish(EC_GROUP *);
|
||||
void ec_GFp_mont_group_clear_finish(EC_GROUP *);
|
||||
int ec_GFp_mont_group_copy(EC_GROUP *, const EC_GROUP *);
|
||||
int ec_GFp_mont_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
|
||||
const BIGNUM *b, BN_CTX *);
|
||||
int ec_GFp_mont_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
|
||||
BN_CTX *);
|
||||
int ec_GFp_mont_field_inv(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
|
||||
BN_CTX *);
|
||||
int ec_GFp_mont_field_encode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
|
||||
BN_CTX *);
|
||||
int ec_GFp_mont_field_decode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
|
||||
BN_CTX *);
|
||||
int ec_GFp_mont_field_set_to_one(const EC_GROUP *, BIGNUM *r, BN_CTX *);
|
||||
|
||||
/* method functions in ecp_nist.c */
|
||||
int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src);
|
||||
int ec_GFp_nist_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a,
|
||||
const BIGNUM *b, BN_CTX *);
|
||||
int ec_GFp_nist_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
|
||||
const BIGNUM *b, BN_CTX *);
|
||||
int ec_GFp_nist_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
|
||||
BN_CTX *);
|
||||
|
||||
/* method functions in ec2_smpl.c */
|
||||
int ec_GF2m_simple_group_init(EC_GROUP *);
|
||||
void ec_GF2m_simple_group_finish(EC_GROUP *);
|
||||
void ec_GF2m_simple_group_clear_finish(EC_GROUP *);
|
||||
int ec_GF2m_simple_group_copy(EC_GROUP *, const EC_GROUP *);
|
||||
int ec_GF2m_simple_group_set_curve(EC_GROUP *, const BIGNUM *p,
|
||||
const BIGNUM *a, const BIGNUM *b,
|
||||
BN_CTX *);
|
||||
int ec_GF2m_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a,
|
||||
BIGNUM *b, BN_CTX *);
|
||||
int ec_GF2m_simple_group_get_degree(const EC_GROUP *);
|
||||
int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *);
|
||||
int ec_GF2m_simple_point_init(EC_POINT *);
|
||||
void ec_GF2m_simple_point_finish(EC_POINT *);
|
||||
void ec_GF2m_simple_point_clear_finish(EC_POINT *);
|
||||
int ec_GF2m_simple_point_copy(EC_POINT *, const EC_POINT *);
|
||||
int ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *);
|
||||
int ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *,
|
||||
const BIGNUM *x,
|
||||
const BIGNUM *y, BN_CTX *);
|
||||
int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *,
|
||||
const EC_POINT *, BIGNUM *x,
|
||||
BIGNUM *y, BN_CTX *);
|
||||
int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *,
|
||||
const BIGNUM *x, int y_bit,
|
||||
BN_CTX *);
|
||||
size_t ec_GF2m_simple_point2oct(const EC_GROUP *, const EC_POINT *,
|
||||
point_conversion_form_t form,
|
||||
unsigned char *buf, size_t len, BN_CTX *);
|
||||
int ec_GF2m_simple_oct2point(const EC_GROUP *, EC_POINT *,
|
||||
const unsigned char *buf, size_t len, BN_CTX *);
|
||||
int ec_GF2m_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
|
||||
const EC_POINT *b, BN_CTX *);
|
||||
int ec_GF2m_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
|
||||
BN_CTX *);
|
||||
int ec_GF2m_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *);
|
||||
int ec_GF2m_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *);
|
||||
int ec_GF2m_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *);
|
||||
int ec_GF2m_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b,
|
||||
BN_CTX *);
|
||||
int ec_GF2m_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
|
||||
int ec_GF2m_simple_points_make_affine(const EC_GROUP *, size_t num,
|
||||
EC_POINT *[], BN_CTX *);
|
||||
int ec_GF2m_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
|
||||
const BIGNUM *b, BN_CTX *);
|
||||
int ec_GF2m_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
|
||||
BN_CTX *);
|
||||
int ec_GF2m_simple_field_div(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
|
||||
const BIGNUM *b, BN_CTX *);
|
||||
|
||||
#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
|
||||
/* method functions in ecp_nistp224.c */
|
||||
int ec_GFp_nistp224_group_init(EC_GROUP *group);
|
||||
int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p,
|
||||
const BIGNUM *a, const BIGNUM *n,
|
||||
BN_CTX *);
|
||||
int ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group,
|
||||
const EC_POINT *point,
|
||||
BIGNUM *x, BIGNUM *y,
|
||||
BN_CTX *ctx);
|
||||
int ec_GFp_nistp224_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
const BIGNUM *scalar, size_t num,
|
||||
const EC_POINT *points[], const BIGNUM *scalars[],
|
||||
BN_CTX *);
|
||||
int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
const BIGNUM *scalar, size_t num,
|
||||
const EC_POINT *points[],
|
||||
const BIGNUM *scalars[], BN_CTX *ctx);
|
||||
int ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
|
||||
int ec_GFp_nistp224_have_precompute_mult(const EC_GROUP *group);
|
||||
|
||||
/* method functions in ecp_nistp256.c */
|
||||
int ec_GFp_nistp256_group_init(EC_GROUP *group);
|
||||
int ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p,
|
||||
const BIGNUM *a, const BIGNUM *n,
|
||||
BN_CTX *);
|
||||
int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group,
|
||||
const EC_POINT *point,
|
||||
BIGNUM *x, BIGNUM *y,
|
||||
BN_CTX *ctx);
|
||||
int ec_GFp_nistp256_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
const BIGNUM *scalar, size_t num,
|
||||
const EC_POINT *points[], const BIGNUM *scalars[],
|
||||
BN_CTX *);
|
||||
int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
const BIGNUM *scalar, size_t num,
|
||||
const EC_POINT *points[],
|
||||
const BIGNUM *scalars[], BN_CTX *ctx);
|
||||
int ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
|
||||
int ec_GFp_nistp256_have_precompute_mult(const EC_GROUP *group);
|
||||
|
||||
/* method functions in ecp_nistp521.c */
|
||||
int ec_GFp_nistp521_group_init(EC_GROUP *group);
|
||||
int ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p,
|
||||
const BIGNUM *a, const BIGNUM *n,
|
||||
BN_CTX *);
|
||||
int ec_GFp_nistp521_point_get_affine_coordinates(const EC_GROUP *group,
|
||||
const EC_POINT *point,
|
||||
BIGNUM *x, BIGNUM *y,
|
||||
BN_CTX *ctx);
|
||||
int ec_GFp_nistp521_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
const BIGNUM *scalar, size_t num,
|
||||
const EC_POINT *points[], const BIGNUM *scalars[],
|
||||
BN_CTX *);
|
||||
int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
const BIGNUM *scalar, size_t num,
|
||||
const EC_POINT *points[],
|
||||
const BIGNUM *scalars[], BN_CTX *ctx);
|
||||
int ec_GFp_nistp521_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
|
||||
int ec_GFp_nistp521_have_precompute_mult(const EC_GROUP *group);
|
||||
|
||||
/* utility functions in ecp_nistputil.c */
|
||||
void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array,
|
||||
size_t felem_size,
|
||||
void *tmp_felems,
|
||||
void (*felem_one) (void *out),
|
||||
int (*felem_is_zero) (const void
|
||||
*in),
|
||||
void (*felem_assign) (void *out,
|
||||
const void
|
||||
*in),
|
||||
void (*felem_square) (void *out,
|
||||
const void
|
||||
*in),
|
||||
void (*felem_mul) (void *out,
|
||||
const void
|
||||
*in1,
|
||||
const void
|
||||
*in2),
|
||||
void (*felem_inv) (void *out,
|
||||
const void
|
||||
*in),
|
||||
void (*felem_contract) (void
|
||||
*out,
|
||||
const
|
||||
void
|
||||
*in));
|
||||
void ec_GFp_nistp_recode_scalar_bits(unsigned char *sign,
|
||||
unsigned char *digit, unsigned char in);
|
||||
#endif
|
||||
int ec_group_simple_order_bits(const EC_GROUP *group);
|
||||
|
||||
#ifdef ECP_NISTZ256_ASM
|
||||
/** Returns GFp methods using montgomery multiplication, with x86-64 optimized
|
||||
* P256. See http://eprint.iacr.org/2013/816.
|
||||
* \return EC_METHOD object
|
||||
*/
|
||||
const EC_METHOD *EC_GFp_nistz256_method(void);
|
||||
#endif
|
||||
|
||||
size_t ec_key_simple_priv2oct(const EC_KEY *eckey,
|
||||
unsigned char *buf, size_t len);
|
||||
int ec_key_simple_oct2priv(EC_KEY *eckey, const unsigned char *buf, size_t len);
|
||||
int ec_key_simple_generate_key(EC_KEY *eckey);
|
||||
int ec_key_simple_generate_public_key(EC_KEY *eckey);
|
||||
int ec_key_simple_check_key(const EC_KEY *eckey);
|
||||
|
||||
/* EC_METHOD definitions */
|
||||
|
||||
struct ec_key_method_st {
|
||||
const char *name;
|
||||
int32_t flags;
|
||||
int (*init)(EC_KEY *key);
|
||||
void (*finish)(EC_KEY *key);
|
||||
int (*copy)(EC_KEY *dest, const EC_KEY *src);
|
||||
int (*set_group)(EC_KEY *key, const EC_GROUP *grp);
|
||||
int (*set_private)(EC_KEY *key, const BIGNUM *priv_key);
|
||||
int (*set_public)(EC_KEY *key, const EC_POINT *pub_key);
|
||||
int (*keygen)(EC_KEY *key);
|
||||
int (*compute_key)(unsigned char **pout, size_t *poutlen,
|
||||
const EC_POINT *pub_key, const EC_KEY *ecdh);
|
||||
int (*sign)(int type, const unsigned char *dgst, int dlen, unsigned char
|
||||
*sig, unsigned int *siglen, const BIGNUM *kinv,
|
||||
const BIGNUM *r, EC_KEY *eckey);
|
||||
int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
|
||||
BIGNUM **rp);
|
||||
ECDSA_SIG *(*sign_sig)(const unsigned char *dgst, int dgst_len,
|
||||
const BIGNUM *in_kinv, const BIGNUM *in_r,
|
||||
EC_KEY *eckey);
|
||||
|
||||
int (*verify)(int type, const unsigned char *dgst, int dgst_len,
|
||||
const unsigned char *sigbuf, int sig_len, EC_KEY *eckey);
|
||||
int (*verify_sig)(const unsigned char *dgst, int dgst_len,
|
||||
const ECDSA_SIG *sig, EC_KEY *eckey);
|
||||
};
|
||||
|
||||
#define EC_KEY_METHOD_DYNAMIC 1
|
||||
|
||||
int ossl_ec_key_gen(EC_KEY *eckey);
|
||||
int ossl_ecdh_compute_key(unsigned char **pout, size_t *poutlen,
|
||||
const EC_POINT *pub_key, const EC_KEY *ecdh);
|
||||
int ecdh_simple_compute_key(unsigned char **pout, size_t *poutlen,
|
||||
const EC_POINT *pub_key, const EC_KEY *ecdh);
|
||||
|
||||
struct ECDSA_SIG_st {
|
||||
BIGNUM *r;
|
||||
BIGNUM *s;
|
||||
};
|
||||
|
||||
int ossl_ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
|
||||
BIGNUM **rp);
|
||||
int ossl_ecdsa_sign(int type, const unsigned char *dgst, int dlen,
|
||||
unsigned char *sig, unsigned int *siglen,
|
||||
const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey);
|
||||
ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len,
|
||||
const BIGNUM *in_kinv, const BIGNUM *in_r,
|
||||
EC_KEY *eckey);
|
||||
int ossl_ecdsa_verify(int type, const unsigned char *dgst, int dgst_len,
|
||||
const unsigned char *sigbuf, int sig_len, EC_KEY *eckey);
|
||||
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],
|
||||
const uint8_t private_key[32]);
|
||||
|
||||
/*-
|
||||
* This functions computes a single point multiplication over the EC group,
|
||||
* using, at a high level, a Montgomery ladder with conditional swaps, with
|
||||
* various timing attack defenses.
|
||||
*
|
||||
* It performs either a fixed point multiplication
|
||||
* (scalar * generator)
|
||||
* when point is NULL, or a variable point multiplication
|
||||
* (scalar * point)
|
||||
* when point is not NULL.
|
||||
*
|
||||
* `scalar` cannot be NULL and should be in the range [0,n) otherwise all
|
||||
* constant time bets are off (where n is the cardinality of the EC group).
|
||||
*
|
||||
* This function expects `group->order` and `group->cardinality` to be well
|
||||
* defined and non-zero: it fails with an error code otherwise.
|
||||
*
|
||||
* NB: This says nothing about the constant-timeness of the ladder step
|
||||
* implementation (i.e., the default implementation is based on EC_POINT_add and
|
||||
* EC_POINT_dbl, which of course are not constant time themselves) or the
|
||||
* underlying multiprecision arithmetic.
|
||||
*
|
||||
* The product is stored in `r`.
|
||||
*
|
||||
* This is an internal function: callers are in charge of ensuring that the
|
||||
* input parameters `group`, `r`, `scalar` and `ctx` are not NULL.
|
||||
*
|
||||
* Returns 1 on success, 0 otherwise.
|
||||
*/
|
||||
int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r,
|
||||
const BIGNUM *scalar, const EC_POINT *point,
|
||||
BN_CTX *ctx);
|
||||
|
||||
int ec_point_blind_coordinates(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx);
|
||||
|
||||
static ossl_inline int ec_point_ladder_pre(const EC_GROUP *group,
|
||||
EC_POINT *r, EC_POINT *s,
|
||||
EC_POINT *p, BN_CTX *ctx)
|
||||
{
|
||||
if (group->meth->ladder_pre != NULL)
|
||||
return group->meth->ladder_pre(group, r, s, p, ctx);
|
||||
|
||||
if (!EC_POINT_copy(s, p)
|
||||
|| !EC_POINT_dbl(group, r, s, ctx))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static ossl_inline int ec_point_ladder_step(const EC_GROUP *group,
|
||||
EC_POINT *r, EC_POINT *s,
|
||||
EC_POINT *p, BN_CTX *ctx)
|
||||
{
|
||||
if (group->meth->ladder_step != NULL)
|
||||
return group->meth->ladder_step(group, r, s, p, ctx);
|
||||
|
||||
if (!EC_POINT_add(group, s, r, s, ctx)
|
||||
|| !EC_POINT_dbl(group, r, r, ctx))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
static ossl_inline int ec_point_ladder_post(const EC_GROUP *group,
|
||||
EC_POINT *r, EC_POINT *s,
|
||||
EC_POINT *p, BN_CTX *ctx)
|
||||
{
|
||||
if (group->meth->ladder_post != NULL)
|
||||
return group->meth->ladder_post(group, r, s, p, ctx);
|
||||
|
||||
return 1;
|
||||
}
|
1121
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ec_lib.c
vendored
Normal file
1121
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ec_lib.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
970
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ec_mult.c
vendored
Normal file
970
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ec_mult.c
vendored
Normal file
|
@ -0,0 +1,970 @@
|
|||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#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
|
||||
* Formerly at:
|
||||
* http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#multiexp
|
||||
* You might now find it here:
|
||||
* http://link.springer.com/chapter/10.1007%2F3-540-45537-X_13
|
||||
* http://www.bmoeller.de/pdf/TI-01-08.multiexp.pdf
|
||||
* For multiplication with precomputation, we use wNAF splitting, formerly at:
|
||||
* http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#fastexp
|
||||
*/
|
||||
|
||||
/* structure for precomputed multiples of the generator */
|
||||
struct ec_pre_comp_st {
|
||||
const EC_GROUP *group; /* parent EC_GROUP object */
|
||||
size_t blocksize; /* block size for wNAF splitting */
|
||||
size_t numblocks; /* max. number of blocks for which we have
|
||||
* precomputation */
|
||||
size_t w; /* window size */
|
||||
EC_POINT **points; /* array with pre-calculated multiples of
|
||||
* generator: 'num' pointers to EC_POINT
|
||||
* objects followed by a NULL */
|
||||
size_t num; /* numblocks * 2^(w-1) */
|
||||
CRYPTO_REF_COUNT references;
|
||||
CRYPTO_RWLOCK *lock;
|
||||
};
|
||||
|
||||
static EC_PRE_COMP *ec_pre_comp_new(const EC_GROUP *group)
|
||||
{
|
||||
EC_PRE_COMP *ret = NULL;
|
||||
|
||||
if (!group)
|
||||
return NULL;
|
||||
|
||||
ret = OPENSSL_zalloc(sizeof(*ret));
|
||||
if (ret == NULL) {
|
||||
ECerr(EC_F_EC_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret->group = group;
|
||||
ret->blocksize = 8; /* default */
|
||||
ret->w = 4; /* default */
|
||||
ret->references = 1;
|
||||
|
||||
ret->lock = CRYPTO_THREAD_lock_new();
|
||||
if (ret->lock == NULL) {
|
||||
ECerr(EC_F_EC_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
|
||||
OPENSSL_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
EC_PRE_COMP *EC_ec_pre_comp_dup(EC_PRE_COMP *pre)
|
||||
{
|
||||
int i;
|
||||
if (pre != NULL)
|
||||
CRYPTO_UP_REF(&pre->references, &i, pre->lock);
|
||||
return pre;
|
||||
}
|
||||
|
||||
void EC_ec_pre_comp_free(EC_PRE_COMP *pre)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (pre == NULL)
|
||||
return;
|
||||
|
||||
CRYPTO_DOWN_REF(&pre->references, &i, pre->lock);
|
||||
REF_PRINT_COUNT("EC_ec", pre);
|
||||
if (i > 0)
|
||||
return;
|
||||
REF_ASSERT_ISNT(i < 0);
|
||||
|
||||
if (pre->points != NULL) {
|
||||
EC_POINT **pts;
|
||||
|
||||
for (pts = pre->points; *pts != NULL; pts++)
|
||||
EC_POINT_free(*pts);
|
||||
OPENSSL_free(pre->points);
|
||||
}
|
||||
CRYPTO_THREAD_lock_free(pre->lock);
|
||||
OPENSSL_free(pre);
|
||||
}
|
||||
|
||||
#define EC_POINT_BN_set_flags(P, flags) do { \
|
||||
BN_set_flags((P)->X, (flags)); \
|
||||
BN_set_flags((P)->Y, (flags)); \
|
||||
BN_set_flags((P)->Z, (flags)); \
|
||||
} while(0)
|
||||
|
||||
/*-
|
||||
* This functions computes a single point multiplication over the EC group,
|
||||
* using, at a high level, a Montgomery ladder with conditional swaps, with
|
||||
* various timing attack defenses.
|
||||
*
|
||||
* It performs either a fixed point multiplication
|
||||
* (scalar * generator)
|
||||
* when point is NULL, or a variable point multiplication
|
||||
* (scalar * point)
|
||||
* when point is not NULL.
|
||||
*
|
||||
* `scalar` cannot be NULL and should be in the range [0,n) otherwise all
|
||||
* constant time bets are off (where n is the cardinality of the EC group).
|
||||
*
|
||||
* This function expects `group->order` and `group->cardinality` to be well
|
||||
* defined and non-zero: it fails with an error code otherwise.
|
||||
*
|
||||
* NB: This says nothing about the constant-timeness of the ladder step
|
||||
* implementation (i.e., the default implementation is based on EC_POINT_add and
|
||||
* EC_POINT_dbl, which of course are not constant time themselves) or the
|
||||
* underlying multiprecision arithmetic.
|
||||
*
|
||||
* The product is stored in `r`.
|
||||
*
|
||||
* This is an internal function: callers are in charge of ensuring that the
|
||||
* input parameters `group`, `r`, `scalar` and `ctx` are not NULL.
|
||||
*
|
||||
* Returns 1 on success, 0 otherwise.
|
||||
*/
|
||||
int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r,
|
||||
const BIGNUM *scalar, const EC_POINT *point,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
int i, cardinality_bits, group_top, kbit, pbit, Z_is_one;
|
||||
EC_POINT *p = NULL;
|
||||
EC_POINT *s = NULL;
|
||||
BIGNUM *k = NULL;
|
||||
BIGNUM *lambda = NULL;
|
||||
BIGNUM *cardinality = NULL;
|
||||
int ret = 0;
|
||||
|
||||
/* early exit if the input point is the point at infinity */
|
||||
if (point != NULL && EC_POINT_is_at_infinity(group, point))
|
||||
return EC_POINT_set_to_infinity(group, r);
|
||||
|
||||
if (BN_is_zero(group->order)) {
|
||||
ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_UNKNOWN_ORDER);
|
||||
return 0;
|
||||
}
|
||||
if (BN_is_zero(group->cofactor)) {
|
||||
ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_UNKNOWN_COFACTOR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
if (((p = EC_POINT_new(group)) == NULL)
|
||||
|| ((s = EC_POINT_new(group)) == NULL)) {
|
||||
ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (point == NULL) {
|
||||
if (!EC_POINT_copy(p, group->generator)) {
|
||||
ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
if (!EC_POINT_copy(p, point)) {
|
||||
ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
EC_POINT_BN_set_flags(p, BN_FLG_CONSTTIME);
|
||||
EC_POINT_BN_set_flags(r, BN_FLG_CONSTTIME);
|
||||
EC_POINT_BN_set_flags(s, BN_FLG_CONSTTIME);
|
||||
|
||||
cardinality = BN_CTX_get(ctx);
|
||||
lambda = BN_CTX_get(ctx);
|
||||
k = BN_CTX_get(ctx);
|
||||
if (k == NULL) {
|
||||
ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!BN_mul(cardinality, group->order, group->cofactor, ctx)) {
|
||||
ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Group cardinalities are often on a word boundary.
|
||||
* So when we pad the scalar, some timing diff might
|
||||
* pop if it needs to be expanded due to carries.
|
||||
* So expand ahead of time.
|
||||
*/
|
||||
cardinality_bits = BN_num_bits(cardinality);
|
||||
group_top = bn_get_top(cardinality);
|
||||
if ((bn_wexpand(k, group_top + 2) == NULL)
|
||||
|| (bn_wexpand(lambda, group_top + 2) == NULL)) {
|
||||
ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!BN_copy(k, scalar)) {
|
||||
ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
|
||||
BN_set_flags(k, BN_FLG_CONSTTIME);
|
||||
|
||||
if ((BN_num_bits(k) > cardinality_bits) || (BN_is_negative(k))) {
|
||||
/*-
|
||||
* this is an unusual input, and we don't guarantee
|
||||
* constant-timeness
|
||||
*/
|
||||
if (!BN_nnmod(k, k, cardinality, ctx)) {
|
||||
ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (!BN_add(lambda, k, cardinality)) {
|
||||
ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
BN_set_flags(lambda, BN_FLG_CONSTTIME);
|
||||
if (!BN_add(k, lambda, cardinality)) {
|
||||
ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
/*
|
||||
* lambda := scalar + cardinality
|
||||
* k := scalar + 2*cardinality
|
||||
*/
|
||||
kbit = BN_is_bit_set(lambda, cardinality_bits);
|
||||
BN_consttime_swap(kbit, k, lambda, group_top + 2);
|
||||
|
||||
group_top = bn_get_top(group->field);
|
||||
if ((bn_wexpand(s->X, group_top) == NULL)
|
||||
|| (bn_wexpand(s->Y, group_top) == NULL)
|
||||
|| (bn_wexpand(s->Z, group_top) == NULL)
|
||||
|| (bn_wexpand(r->X, group_top) == NULL)
|
||||
|| (bn_wexpand(r->Y, group_top) == NULL)
|
||||
|| (bn_wexpand(r->Z, group_top) == NULL)
|
||||
|| (bn_wexpand(p->X, group_top) == NULL)
|
||||
|| (bn_wexpand(p->Y, group_top) == NULL)
|
||||
|| (bn_wexpand(p->Z, group_top) == NULL)) {
|
||||
ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/*-
|
||||
* Apply coordinate blinding for EC_POINT.
|
||||
*
|
||||
* The underlying EC_METHOD can optionally implement this function:
|
||||
* ec_point_blind_coordinates() returns 0 in case of errors or 1 on
|
||||
* success or if coordinate blinding is not implemented for this
|
||||
* group.
|
||||
*/
|
||||
if (!ec_point_blind_coordinates(group, p, ctx)) {
|
||||
ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_POINT_COORDINATES_BLIND_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Initialize the Montgomery ladder */
|
||||
if (!ec_point_ladder_pre(group, r, s, p, ctx)) {
|
||||
ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_LADDER_PRE_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* top bit is a 1, in a fixed pos */
|
||||
pbit = 1;
|
||||
|
||||
#define EC_POINT_CSWAP(c, a, b, w, t) do { \
|
||||
BN_consttime_swap(c, (a)->X, (b)->X, w); \
|
||||
BN_consttime_swap(c, (a)->Y, (b)->Y, w); \
|
||||
BN_consttime_swap(c, (a)->Z, (b)->Z, w); \
|
||||
t = ((a)->Z_is_one ^ (b)->Z_is_one) & (c); \
|
||||
(a)->Z_is_one ^= (t); \
|
||||
(b)->Z_is_one ^= (t); \
|
||||
} while(0)
|
||||
|
||||
/*-
|
||||
* The ladder step, with branches, is
|
||||
*
|
||||
* k[i] == 0: S = add(R, S), R = dbl(R)
|
||||
* k[i] == 1: R = add(S, R), S = dbl(S)
|
||||
*
|
||||
* Swapping R, S conditionally on k[i] leaves you with state
|
||||
*
|
||||
* k[i] == 0: T, U = R, S
|
||||
* k[i] == 1: T, U = S, R
|
||||
*
|
||||
* Then perform the ECC ops.
|
||||
*
|
||||
* U = add(T, U)
|
||||
* T = dbl(T)
|
||||
*
|
||||
* Which leaves you with state
|
||||
*
|
||||
* k[i] == 0: U = add(R, S), T = dbl(R)
|
||||
* k[i] == 1: U = add(S, R), T = dbl(S)
|
||||
*
|
||||
* Swapping T, U conditionally on k[i] leaves you with state
|
||||
*
|
||||
* k[i] == 0: R, S = T, U
|
||||
* k[i] == 1: R, S = U, T
|
||||
*
|
||||
* Which leaves you with state
|
||||
*
|
||||
* k[i] == 0: S = add(R, S), R = dbl(R)
|
||||
* k[i] == 1: R = add(S, R), S = dbl(S)
|
||||
*
|
||||
* So we get the same logic, but instead of a branch it's a
|
||||
* conditional swap, followed by ECC ops, then another conditional swap.
|
||||
*
|
||||
* Optimization: The end of iteration i and start of i-1 looks like
|
||||
*
|
||||
* ...
|
||||
* CSWAP(k[i], R, S)
|
||||
* ECC
|
||||
* CSWAP(k[i], R, S)
|
||||
* (next iteration)
|
||||
* CSWAP(k[i-1], R, S)
|
||||
* ECC
|
||||
* CSWAP(k[i-1], R, S)
|
||||
* ...
|
||||
*
|
||||
* So instead of two contiguous swaps, you can merge the condition
|
||||
* bits and do a single swap.
|
||||
*
|
||||
* k[i] k[i-1] Outcome
|
||||
* 0 0 No Swap
|
||||
* 0 1 Swap
|
||||
* 1 0 Swap
|
||||
* 1 1 No Swap
|
||||
*
|
||||
* This is XOR. pbit tracks the previous bit of k.
|
||||
*/
|
||||
|
||||
for (i = cardinality_bits - 1; i >= 0; i--) {
|
||||
kbit = BN_is_bit_set(k, i) ^ pbit;
|
||||
EC_POINT_CSWAP(kbit, r, s, group_top, Z_is_one);
|
||||
|
||||
/* Perform a single step of the Montgomery ladder */
|
||||
if (!ec_point_ladder_step(group, r, s, p, ctx)) {
|
||||
ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_LADDER_STEP_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
/*
|
||||
* pbit logic merges this cswap with that of the
|
||||
* next iteration
|
||||
*/
|
||||
pbit ^= kbit;
|
||||
}
|
||||
/* one final cswap to move the right value into r */
|
||||
EC_POINT_CSWAP(pbit, r, s, group_top, Z_is_one);
|
||||
#undef EC_POINT_CSWAP
|
||||
|
||||
/* Finalize ladder (and recover full point coordinates) */
|
||||
if (!ec_point_ladder_post(group, r, s, p, ctx)) {
|
||||
ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_LADDER_POST_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
EC_POINT_free(p);
|
||||
EC_POINT_free(s);
|
||||
BN_CTX_end(ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef EC_POINT_BN_set_flags
|
||||
|
||||
/*
|
||||
* TODO: table should be optimised for the wNAF-based implementation,
|
||||
* sometimes smaller windows will give better performance (thus the
|
||||
* boundaries should be increased)
|
||||
*/
|
||||
#define EC_window_bits_for_scalar_size(b) \
|
||||
((size_t) \
|
||||
((b) >= 2000 ? 6 : \
|
||||
(b) >= 800 ? 5 : \
|
||||
(b) >= 300 ? 4 : \
|
||||
(b) >= 70 ? 3 : \
|
||||
(b) >= 20 ? 2 : \
|
||||
1))
|
||||
|
||||
/*-
|
||||
* Compute
|
||||
* \sum scalars[i]*points[i],
|
||||
* also including
|
||||
* scalar*generator
|
||||
* in the addition if scalar != NULL
|
||||
*/
|
||||
int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
||||
size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
const EC_POINT *generator = NULL;
|
||||
EC_POINT *tmp = NULL;
|
||||
size_t totalnum;
|
||||
size_t blocksize = 0, numblocks = 0; /* for wNAF splitting */
|
||||
size_t pre_points_per_block = 0;
|
||||
size_t i, j;
|
||||
int k;
|
||||
int r_is_inverted = 0;
|
||||
int r_is_at_infinity = 1;
|
||||
size_t *wsize = NULL; /* individual window sizes */
|
||||
signed char **wNAF = NULL; /* individual wNAFs */
|
||||
size_t *wNAF_len = NULL;
|
||||
size_t max_len = 0;
|
||||
size_t num_val;
|
||||
EC_POINT **val = NULL; /* precomputation */
|
||||
EC_POINT **v;
|
||||
EC_POINT ***val_sub = NULL; /* pointers to sub-arrays of 'val' or
|
||||
* 'pre_comp->points' */
|
||||
const EC_PRE_COMP *pre_comp = NULL;
|
||||
int num_scalar = 0; /* flag: will be set to 1 if 'scalar' must be
|
||||
* treated like other scalars, i.e.
|
||||
* precomputation is not available */
|
||||
int ret = 0;
|
||||
|
||||
if (!BN_is_zero(group->order) && !BN_is_zero(group->cofactor)) {
|
||||
/*-
|
||||
* Handle the common cases where the scalar is secret, enforcing a
|
||||
* scalar multiplication implementation based on a Montgomery ladder,
|
||||
* with various timing attack defenses.
|
||||
*/
|
||||
if ((scalar != NULL) && (num == 0)) {
|
||||
/*-
|
||||
* In this case we want to compute scalar * GeneratorPoint: this
|
||||
* codepath is reached most prominently by (ephemeral) key
|
||||
* generation of EC cryptosystems (i.e. ECDSA keygen and sign setup,
|
||||
* ECDH keygen/first half), where the scalar is always secret. This
|
||||
* is why we ignore if BN_FLG_CONSTTIME is actually set and we
|
||||
* always call the ladder version.
|
||||
*/
|
||||
return ec_scalar_mul_ladder(group, r, scalar, NULL, ctx);
|
||||
}
|
||||
if ((scalar == NULL) && (num == 1)) {
|
||||
/*-
|
||||
* In this case we want to compute scalar * VariablePoint: this
|
||||
* codepath is reached most prominently by the second half of ECDH,
|
||||
* where the secret scalar is multiplied by the peer's public point.
|
||||
* To protect the secret scalar, we ignore if BN_FLG_CONSTTIME is
|
||||
* actually set and we always call the ladder version.
|
||||
*/
|
||||
return ec_scalar_mul_ladder(group, r, scalars[0], points[0], ctx);
|
||||
}
|
||||
}
|
||||
|
||||
if (scalar != NULL) {
|
||||
generator = EC_GROUP_get0_generator(group);
|
||||
if (generator == NULL) {
|
||||
ECerr(EC_F_EC_WNAF_MUL, EC_R_UNDEFINED_GENERATOR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* look if we can use precomputed multiples of generator */
|
||||
|
||||
pre_comp = group->pre_comp.ec;
|
||||
if (pre_comp && pre_comp->numblocks
|
||||
&& (EC_POINT_cmp(group, generator, pre_comp->points[0], ctx) ==
|
||||
0)) {
|
||||
blocksize = pre_comp->blocksize;
|
||||
|
||||
/*
|
||||
* determine maximum number of blocks that wNAF splitting may
|
||||
* yield (NB: maximum wNAF length is bit length plus one)
|
||||
*/
|
||||
numblocks = (BN_num_bits(scalar) / blocksize) + 1;
|
||||
|
||||
/*
|
||||
* we cannot use more blocks than we have precomputation for
|
||||
*/
|
||||
if (numblocks > pre_comp->numblocks)
|
||||
numblocks = pre_comp->numblocks;
|
||||
|
||||
pre_points_per_block = (size_t)1 << (pre_comp->w - 1);
|
||||
|
||||
/* check that pre_comp looks sane */
|
||||
if (pre_comp->num != (pre_comp->numblocks * pre_points_per_block)) {
|
||||
ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
/* can't use precomputation */
|
||||
pre_comp = NULL;
|
||||
numblocks = 1;
|
||||
num_scalar = 1; /* treat 'scalar' like 'num'-th element of
|
||||
* 'scalars' */
|
||||
}
|
||||
}
|
||||
|
||||
totalnum = num + numblocks;
|
||||
|
||||
wsize = OPENSSL_malloc(totalnum * sizeof(wsize[0]));
|
||||
wNAF_len = OPENSSL_malloc(totalnum * sizeof(wNAF_len[0]));
|
||||
/* include space for pivot */
|
||||
wNAF = OPENSSL_malloc((totalnum + 1) * sizeof(wNAF[0]));
|
||||
val_sub = OPENSSL_malloc(totalnum * sizeof(val_sub[0]));
|
||||
|
||||
/* Ensure wNAF is initialised in case we end up going to err */
|
||||
if (wNAF != NULL)
|
||||
wNAF[0] = NULL; /* preliminary pivot */
|
||||
|
||||
if (wsize == NULL || wNAF_len == NULL || wNAF == NULL || val_sub == NULL) {
|
||||
ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
* num_val will be the total number of temporarily precomputed points
|
||||
*/
|
||||
num_val = 0;
|
||||
|
||||
for (i = 0; i < num + num_scalar; i++) {
|
||||
size_t bits;
|
||||
|
||||
bits = i < num ? BN_num_bits(scalars[i]) : BN_num_bits(scalar);
|
||||
wsize[i] = EC_window_bits_for_scalar_size(bits);
|
||||
num_val += (size_t)1 << (wsize[i] - 1);
|
||||
wNAF[i + 1] = NULL; /* make sure we always have a pivot */
|
||||
wNAF[i] =
|
||||
bn_compute_wNAF((i < num ? scalars[i] : scalar), wsize[i],
|
||||
&wNAF_len[i]);
|
||||
if (wNAF[i] == NULL)
|
||||
goto err;
|
||||
if (wNAF_len[i] > max_len)
|
||||
max_len = wNAF_len[i];
|
||||
}
|
||||
|
||||
if (numblocks) {
|
||||
/* we go here iff scalar != NULL */
|
||||
|
||||
if (pre_comp == NULL) {
|
||||
if (num_scalar != 1) {
|
||||
ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
/* we have already generated a wNAF for 'scalar' */
|
||||
} else {
|
||||
signed char *tmp_wNAF = NULL;
|
||||
size_t tmp_len = 0;
|
||||
|
||||
if (num_scalar != 0) {
|
||||
ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
* use the window size for which we have precomputation
|
||||
*/
|
||||
wsize[num] = pre_comp->w;
|
||||
tmp_wNAF = bn_compute_wNAF(scalar, wsize[num], &tmp_len);
|
||||
if (!tmp_wNAF)
|
||||
goto err;
|
||||
|
||||
if (tmp_len <= max_len) {
|
||||
/*
|
||||
* One of the other wNAFs is at least as long as the wNAF
|
||||
* belonging to the generator, so wNAF splitting will not buy
|
||||
* us anything.
|
||||
*/
|
||||
|
||||
numblocks = 1;
|
||||
totalnum = num + 1; /* don't use wNAF splitting */
|
||||
wNAF[num] = tmp_wNAF;
|
||||
wNAF[num + 1] = NULL;
|
||||
wNAF_len[num] = tmp_len;
|
||||
/*
|
||||
* pre_comp->points starts with the points that we need here:
|
||||
*/
|
||||
val_sub[num] = pre_comp->points;
|
||||
} else {
|
||||
/*
|
||||
* don't include tmp_wNAF directly into wNAF array - use wNAF
|
||||
* splitting and include the blocks
|
||||
*/
|
||||
|
||||
signed char *pp;
|
||||
EC_POINT **tmp_points;
|
||||
|
||||
if (tmp_len < numblocks * blocksize) {
|
||||
/*
|
||||
* possibly we can do with fewer blocks than estimated
|
||||
*/
|
||||
numblocks = (tmp_len + blocksize - 1) / blocksize;
|
||||
if (numblocks > pre_comp->numblocks) {
|
||||
ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
|
||||
OPENSSL_free(tmp_wNAF);
|
||||
goto err;
|
||||
}
|
||||
totalnum = num + numblocks;
|
||||
}
|
||||
|
||||
/* split wNAF in 'numblocks' parts */
|
||||
pp = tmp_wNAF;
|
||||
tmp_points = pre_comp->points;
|
||||
|
||||
for (i = num; i < totalnum; i++) {
|
||||
if (i < totalnum - 1) {
|
||||
wNAF_len[i] = blocksize;
|
||||
if (tmp_len < blocksize) {
|
||||
ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
|
||||
OPENSSL_free(tmp_wNAF);
|
||||
goto err;
|
||||
}
|
||||
tmp_len -= blocksize;
|
||||
} else
|
||||
/*
|
||||
* last block gets whatever is left (this could be
|
||||
* more or less than 'blocksize'!)
|
||||
*/
|
||||
wNAF_len[i] = tmp_len;
|
||||
|
||||
wNAF[i + 1] = NULL;
|
||||
wNAF[i] = OPENSSL_malloc(wNAF_len[i]);
|
||||
if (wNAF[i] == NULL) {
|
||||
ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
|
||||
OPENSSL_free(tmp_wNAF);
|
||||
goto err;
|
||||
}
|
||||
memcpy(wNAF[i], pp, wNAF_len[i]);
|
||||
if (wNAF_len[i] > max_len)
|
||||
max_len = wNAF_len[i];
|
||||
|
||||
if (*tmp_points == NULL) {
|
||||
ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
|
||||
OPENSSL_free(tmp_wNAF);
|
||||
goto err;
|
||||
}
|
||||
val_sub[i] = tmp_points;
|
||||
tmp_points += pre_points_per_block;
|
||||
pp += blocksize;
|
||||
}
|
||||
OPENSSL_free(tmp_wNAF);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* All points we precompute now go into a single array 'val'.
|
||||
* 'val_sub[i]' is a pointer to the subarray for the i-th point, or to a
|
||||
* subarray of 'pre_comp->points' if we already have precomputation.
|
||||
*/
|
||||
val = OPENSSL_malloc((num_val + 1) * sizeof(val[0]));
|
||||
if (val == NULL) {
|
||||
ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
val[num_val] = NULL; /* pivot element */
|
||||
|
||||
/* allocate points for precomputation */
|
||||
v = val;
|
||||
for (i = 0; i < num + num_scalar; i++) {
|
||||
val_sub[i] = v;
|
||||
for (j = 0; j < ((size_t)1 << (wsize[i] - 1)); j++) {
|
||||
*v = EC_POINT_new(group);
|
||||
if (*v == NULL)
|
||||
goto err;
|
||||
v++;
|
||||
}
|
||||
}
|
||||
if (!(v == val + num_val)) {
|
||||
ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((tmp = EC_POINT_new(group)) == NULL)
|
||||
goto err;
|
||||
|
||||
/*-
|
||||
* prepare precomputed values:
|
||||
* val_sub[i][0] := points[i]
|
||||
* val_sub[i][1] := 3 * points[i]
|
||||
* val_sub[i][2] := 5 * points[i]
|
||||
* ...
|
||||
*/
|
||||
for (i = 0; i < num + num_scalar; i++) {
|
||||
if (i < num) {
|
||||
if (!EC_POINT_copy(val_sub[i][0], points[i]))
|
||||
goto err;
|
||||
} else {
|
||||
if (!EC_POINT_copy(val_sub[i][0], generator))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (wsize[i] > 1) {
|
||||
if (!EC_POINT_dbl(group, tmp, val_sub[i][0], ctx))
|
||||
goto err;
|
||||
for (j = 1; j < ((size_t)1 << (wsize[i] - 1)); j++) {
|
||||
if (!EC_POINT_add
|
||||
(group, val_sub[i][j], val_sub[i][j - 1], tmp, ctx))
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!EC_POINTs_make_affine(group, num_val, val, ctx))
|
||||
goto err;
|
||||
|
||||
r_is_at_infinity = 1;
|
||||
|
||||
for (k = max_len - 1; k >= 0; k--) {
|
||||
if (!r_is_at_infinity) {
|
||||
if (!EC_POINT_dbl(group, r, r, ctx))
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (i = 0; i < totalnum; i++) {
|
||||
if (wNAF_len[i] > (size_t)k) {
|
||||
int digit = wNAF[i][k];
|
||||
int is_neg;
|
||||
|
||||
if (digit) {
|
||||
is_neg = digit < 0;
|
||||
|
||||
if (is_neg)
|
||||
digit = -digit;
|
||||
|
||||
if (is_neg != r_is_inverted) {
|
||||
if (!r_is_at_infinity) {
|
||||
if (!EC_POINT_invert(group, r, ctx))
|
||||
goto err;
|
||||
}
|
||||
r_is_inverted = !r_is_inverted;
|
||||
}
|
||||
|
||||
/* digit > 0 */
|
||||
|
||||
if (r_is_at_infinity) {
|
||||
if (!EC_POINT_copy(r, val_sub[i][digit >> 1]))
|
||||
goto err;
|
||||
r_is_at_infinity = 0;
|
||||
} else {
|
||||
if (!EC_POINT_add
|
||||
(group, r, r, val_sub[i][digit >> 1], ctx))
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (r_is_at_infinity) {
|
||||
if (!EC_POINT_set_to_infinity(group, r))
|
||||
goto err;
|
||||
} else {
|
||||
if (r_is_inverted)
|
||||
if (!EC_POINT_invert(group, r, ctx))
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
EC_POINT_free(tmp);
|
||||
OPENSSL_free(wsize);
|
||||
OPENSSL_free(wNAF_len);
|
||||
if (wNAF != NULL) {
|
||||
signed char **w;
|
||||
|
||||
for (w = wNAF; *w != NULL; w++)
|
||||
OPENSSL_free(*w);
|
||||
|
||||
OPENSSL_free(wNAF);
|
||||
}
|
||||
if (val != NULL) {
|
||||
for (v = val; *v != NULL; v++)
|
||||
EC_POINT_clear_free(*v);
|
||||
|
||||
OPENSSL_free(val);
|
||||
}
|
||||
OPENSSL_free(val_sub);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*-
|
||||
* ec_wNAF_precompute_mult()
|
||||
* creates an EC_PRE_COMP object with preprecomputed multiples of the generator
|
||||
* for use with wNAF splitting as implemented in ec_wNAF_mul().
|
||||
*
|
||||
* 'pre_comp->points' is an array of multiples of the generator
|
||||
* of the following form:
|
||||
* points[0] = generator;
|
||||
* points[1] = 3 * generator;
|
||||
* ...
|
||||
* points[2^(w-1)-1] = (2^(w-1)-1) * generator;
|
||||
* points[2^(w-1)] = 2^blocksize * generator;
|
||||
* points[2^(w-1)+1] = 3 * 2^blocksize * generator;
|
||||
* ...
|
||||
* points[2^(w-1)*(numblocks-1)-1] = (2^(w-1)) * 2^(blocksize*(numblocks-2)) * generator
|
||||
* points[2^(w-1)*(numblocks-1)] = 2^(blocksize*(numblocks-1)) * generator
|
||||
* ...
|
||||
* points[2^(w-1)*numblocks-1] = (2^(w-1)) * 2^(blocksize*(numblocks-1)) * generator
|
||||
* points[2^(w-1)*numblocks] = NULL
|
||||
*/
|
||||
int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
|
||||
{
|
||||
const EC_POINT *generator;
|
||||
EC_POINT *tmp_point = NULL, *base = NULL, **var;
|
||||
BN_CTX *new_ctx = NULL;
|
||||
const BIGNUM *order;
|
||||
size_t i, bits, w, pre_points_per_block, blocksize, numblocks, num;
|
||||
EC_POINT **points = NULL;
|
||||
EC_PRE_COMP *pre_comp;
|
||||
int ret = 0;
|
||||
|
||||
/* if there is an old EC_PRE_COMP object, throw it away */
|
||||
EC_pre_comp_free(group);
|
||||
if ((pre_comp = ec_pre_comp_new(group)) == NULL)
|
||||
return 0;
|
||||
|
||||
generator = EC_GROUP_get0_generator(group);
|
||||
if (generator == NULL) {
|
||||
ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, EC_R_UNDEFINED_GENERATOR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (ctx == NULL) {
|
||||
ctx = new_ctx = BN_CTX_new();
|
||||
if (ctx == NULL)
|
||||
goto err;
|
||||
}
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
order = EC_GROUP_get0_order(group);
|
||||
if (order == NULL)
|
||||
goto err;
|
||||
if (BN_is_zero(order)) {
|
||||
ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, EC_R_UNKNOWN_ORDER);
|
||||
goto err;
|
||||
}
|
||||
|
||||
bits = BN_num_bits(order);
|
||||
/*
|
||||
* The following parameters mean we precompute (approximately) one point
|
||||
* per bit. TBD: The combination 8, 4 is perfect for 160 bits; for other
|
||||
* bit lengths, other parameter combinations might provide better
|
||||
* efficiency.
|
||||
*/
|
||||
blocksize = 8;
|
||||
w = 4;
|
||||
if (EC_window_bits_for_scalar_size(bits) > w) {
|
||||
/* let's not make the window too small ... */
|
||||
w = EC_window_bits_for_scalar_size(bits);
|
||||
}
|
||||
|
||||
numblocks = (bits + blocksize - 1) / blocksize; /* max. number of blocks
|
||||
* to use for wNAF
|
||||
* splitting */
|
||||
|
||||
pre_points_per_block = (size_t)1 << (w - 1);
|
||||
num = pre_points_per_block * numblocks; /* number of points to compute
|
||||
* and store */
|
||||
|
||||
points = OPENSSL_malloc(sizeof(*points) * (num + 1));
|
||||
if (points == NULL) {
|
||||
ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
var = points;
|
||||
var[num] = NULL; /* pivot */
|
||||
for (i = 0; i < num; i++) {
|
||||
if ((var[i] = EC_POINT_new(group)) == NULL) {
|
||||
ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if ((tmp_point = EC_POINT_new(group)) == NULL
|
||||
|| (base = EC_POINT_new(group)) == NULL) {
|
||||
ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!EC_POINT_copy(base, generator))
|
||||
goto err;
|
||||
|
||||
/* do the precomputation */
|
||||
for (i = 0; i < numblocks; i++) {
|
||||
size_t j;
|
||||
|
||||
if (!EC_POINT_dbl(group, tmp_point, base, ctx))
|
||||
goto err;
|
||||
|
||||
if (!EC_POINT_copy(*var++, base))
|
||||
goto err;
|
||||
|
||||
for (j = 1; j < pre_points_per_block; j++, var++) {
|
||||
/*
|
||||
* calculate odd multiples of the current base point
|
||||
*/
|
||||
if (!EC_POINT_add(group, *var, tmp_point, *(var - 1), ctx))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (i < numblocks - 1) {
|
||||
/*
|
||||
* get the next base (multiply current one by 2^blocksize)
|
||||
*/
|
||||
size_t k;
|
||||
|
||||
if (blocksize <= 2) {
|
||||
ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!EC_POINT_dbl(group, base, tmp_point, ctx))
|
||||
goto err;
|
||||
for (k = 2; k < blocksize; k++) {
|
||||
if (!EC_POINT_dbl(group, base, base, ctx))
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!EC_POINTs_make_affine(group, num, points, ctx))
|
||||
goto err;
|
||||
|
||||
pre_comp->group = group;
|
||||
pre_comp->blocksize = blocksize;
|
||||
pre_comp->numblocks = numblocks;
|
||||
pre_comp->w = w;
|
||||
pre_comp->points = points;
|
||||
points = NULL;
|
||||
pre_comp->num = num;
|
||||
SETPRECOMP(group, ec, pre_comp);
|
||||
pre_comp = NULL;
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
if (ctx != NULL)
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
EC_ec_pre_comp_free(pre_comp);
|
||||
if (points) {
|
||||
EC_POINT **p;
|
||||
|
||||
for (p = points; *p != NULL; p++)
|
||||
EC_POINT_free(*p);
|
||||
OPENSSL_free(points);
|
||||
}
|
||||
EC_POINT_free(tmp_point);
|
||||
EC_POINT_free(base);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ec_wNAF_have_precompute_mult(const EC_GROUP *group)
|
||||
{
|
||||
return HAVEPRECOMP(group, ec);
|
||||
}
|
150
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ec_oct.c
vendored
Normal file
150
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ec_oct.c
vendored
Normal file
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
* Copyright 2011-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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/opensslv.h>
|
||||
|
||||
#include "ec_lcl.h"
|
||||
|
||||
int EC_POINT_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
|
||||
const BIGNUM *x, int y_bit, BN_CTX *ctx)
|
||||
{
|
||||
if (group->meth->point_set_compressed_coordinates == NULL
|
||||
&& !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
|
||||
ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES,
|
||||
ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
||||
return 0;
|
||||
}
|
||||
if (!ec_point_is_compat(point, group)) {
|
||||
ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES,
|
||||
EC_R_INCOMPATIBLE_OBJECTS);
|
||||
return 0;
|
||||
}
|
||||
if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
|
||||
if (group->meth->field_type == NID_X9_62_prime_field)
|
||||
return ec_GFp_simple_set_compressed_coordinates(group, point, x,
|
||||
y_bit, ctx);
|
||||
else
|
||||
#ifdef OPENSSL_NO_EC2M
|
||||
{
|
||||
ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES,
|
||||
EC_R_GF2M_NOT_SUPPORTED);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
return ec_GF2m_simple_set_compressed_coordinates(group, point, x,
|
||||
y_bit, ctx);
|
||||
#endif
|
||||
}
|
||||
return group->meth->point_set_compressed_coordinates(group, point, x,
|
||||
y_bit, ctx);
|
||||
}
|
||||
|
||||
#if OPENSSL_API_COMPAT < 0x10200000L
|
||||
int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group,
|
||||
EC_POINT *point, const BIGNUM *x,
|
||||
int y_bit, BN_CTX *ctx)
|
||||
{
|
||||
return EC_POINT_set_compressed_coordinates(group, point, x, y_bit, ctx);
|
||||
}
|
||||
|
||||
# ifndef OPENSSL_NO_EC2M
|
||||
int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group,
|
||||
EC_POINT *point, const BIGNUM *x,
|
||||
int y_bit, BN_CTX *ctx)
|
||||
{
|
||||
return EC_POINT_set_compressed_coordinates(group, point, x, y_bit, ctx);
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point,
|
||||
point_conversion_form_t form, unsigned char *buf,
|
||||
size_t len, BN_CTX *ctx)
|
||||
{
|
||||
if (group->meth->point2oct == 0
|
||||
&& !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
|
||||
ECerr(EC_F_EC_POINT_POINT2OCT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
||||
return 0;
|
||||
}
|
||||
if (!ec_point_is_compat(point, group)) {
|
||||
ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_INCOMPATIBLE_OBJECTS);
|
||||
return 0;
|
||||
}
|
||||
if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
|
||||
if (group->meth->field_type == NID_X9_62_prime_field)
|
||||
return ec_GFp_simple_point2oct(group, point, form, buf, len, ctx);
|
||||
else
|
||||
#ifdef OPENSSL_NO_EC2M
|
||||
{
|
||||
ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_GF2M_NOT_SUPPORTED);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
return ec_GF2m_simple_point2oct(group, point,
|
||||
form, buf, len, ctx);
|
||||
#endif
|
||||
}
|
||||
|
||||
return group->meth->point2oct(group, point, form, buf, len, ctx);
|
||||
}
|
||||
|
||||
int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point,
|
||||
const unsigned char *buf, size_t len, BN_CTX *ctx)
|
||||
{
|
||||
if (group->meth->oct2point == 0
|
||||
&& !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
|
||||
ECerr(EC_F_EC_POINT_OCT2POINT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
||||
return 0;
|
||||
}
|
||||
if (!ec_point_is_compat(point, group)) {
|
||||
ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_INCOMPATIBLE_OBJECTS);
|
||||
return 0;
|
||||
}
|
||||
if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
|
||||
if (group->meth->field_type == NID_X9_62_prime_field)
|
||||
return ec_GFp_simple_oct2point(group, point, buf, len, ctx);
|
||||
else
|
||||
#ifdef OPENSSL_NO_EC2M
|
||||
{
|
||||
ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_GF2M_NOT_SUPPORTED);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
return ec_GF2m_simple_oct2point(group, point, buf, len, ctx);
|
||||
#endif
|
||||
}
|
||||
return group->meth->oct2point(group, point, buf, len, ctx);
|
||||
}
|
||||
|
||||
size_t EC_POINT_point2buf(const EC_GROUP *group, const EC_POINT *point,
|
||||
point_conversion_form_t form,
|
||||
unsigned char **pbuf, BN_CTX *ctx)
|
||||
{
|
||||
size_t len;
|
||||
unsigned char *buf;
|
||||
|
||||
len = EC_POINT_point2oct(group, point, form, NULL, 0, NULL);
|
||||
if (len == 0)
|
||||
return 0;
|
||||
if ((buf = OPENSSL_malloc(len)) == NULL) {
|
||||
ECerr(EC_F_EC_POINT_POINT2BUF, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
len = EC_POINT_point2oct(group, point, form, buf, len, ctx);
|
||||
if (len == 0) {
|
||||
OPENSSL_free(buf);
|
||||
return 0;
|
||||
}
|
||||
*pbuf = buf;
|
||||
return len;
|
||||
}
|
472
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ec_pmeth.c
vendored
Normal file
472
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ec_pmeth.c
vendored
Normal file
|
@ -0,0 +1,472 @@
|
|||
/*
|
||||
* Copyright 2006-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
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/asn1t.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/ec.h>
|
||||
#include "ec_lcl.h"
|
||||
#include <openssl/evp.h>
|
||||
#include "internal/evp_int.h"
|
||||
|
||||
/* EC pkey context structure */
|
||||
|
||||
typedef struct {
|
||||
/* Key and paramgen group */
|
||||
EC_GROUP *gen_group;
|
||||
/* message digest */
|
||||
const EVP_MD *md;
|
||||
/* Duplicate key if custom cofactor needed */
|
||||
EC_KEY *co_key;
|
||||
/* Cofactor mode */
|
||||
signed char cofactor_mode;
|
||||
/* KDF (if any) to use for ECDH */
|
||||
char kdf_type;
|
||||
/* Message digest to use for key derivation */
|
||||
const EVP_MD *kdf_md;
|
||||
/* User key material */
|
||||
unsigned char *kdf_ukm;
|
||||
size_t kdf_ukmlen;
|
||||
/* KDF output length */
|
||||
size_t kdf_outlen;
|
||||
} EC_PKEY_CTX;
|
||||
|
||||
static int pkey_ec_init(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
EC_PKEY_CTX *dctx;
|
||||
|
||||
if ((dctx = OPENSSL_zalloc(sizeof(*dctx))) == NULL) {
|
||||
ECerr(EC_F_PKEY_EC_INIT, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dctx->cofactor_mode = -1;
|
||||
dctx->kdf_type = EVP_PKEY_ECDH_KDF_NONE;
|
||||
ctx->data = dctx;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pkey_ec_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
|
||||
{
|
||||
EC_PKEY_CTX *dctx, *sctx;
|
||||
if (!pkey_ec_init(dst))
|
||||
return 0;
|
||||
sctx = src->data;
|
||||
dctx = dst->data;
|
||||
if (sctx->gen_group) {
|
||||
dctx->gen_group = EC_GROUP_dup(sctx->gen_group);
|
||||
if (!dctx->gen_group)
|
||||
return 0;
|
||||
}
|
||||
dctx->md = sctx->md;
|
||||
|
||||
if (sctx->co_key) {
|
||||
dctx->co_key = EC_KEY_dup(sctx->co_key);
|
||||
if (!dctx->co_key)
|
||||
return 0;
|
||||
}
|
||||
dctx->kdf_type = sctx->kdf_type;
|
||||
dctx->kdf_md = sctx->kdf_md;
|
||||
dctx->kdf_outlen = sctx->kdf_outlen;
|
||||
if (sctx->kdf_ukm) {
|
||||
dctx->kdf_ukm = OPENSSL_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen);
|
||||
if (!dctx->kdf_ukm)
|
||||
return 0;
|
||||
} else
|
||||
dctx->kdf_ukm = NULL;
|
||||
dctx->kdf_ukmlen = sctx->kdf_ukmlen;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void pkey_ec_cleanup(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
EC_PKEY_CTX *dctx = ctx->data;
|
||||
if (dctx != NULL) {
|
||||
EC_GROUP_free(dctx->gen_group);
|
||||
EC_KEY_free(dctx->co_key);
|
||||
OPENSSL_free(dctx->kdf_ukm);
|
||||
OPENSSL_free(dctx);
|
||||
ctx->data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int pkey_ec_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
|
||||
const unsigned char *tbs, size_t tbslen)
|
||||
{
|
||||
int ret, type;
|
||||
unsigned int sltmp;
|
||||
EC_PKEY_CTX *dctx = ctx->data;
|
||||
EC_KEY *ec = ctx->pkey->pkey.ec;
|
||||
const int sig_sz = ECDSA_size(ec);
|
||||
|
||||
/* ensure cast to size_t is safe */
|
||||
if (!ossl_assert(sig_sz > 0))
|
||||
return 0;
|
||||
|
||||
if (sig == NULL) {
|
||||
*siglen = (size_t)sig_sz;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (*siglen < (size_t)sig_sz) {
|
||||
ECerr(EC_F_PKEY_EC_SIGN, EC_R_BUFFER_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
type = (dctx->md != NULL) ? EVP_MD_type(dctx->md) : NID_sha1;
|
||||
|
||||
ret = ECDSA_sign(type, tbs, tbslen, sig, &sltmp, ec);
|
||||
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
*siglen = (size_t)sltmp;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pkey_ec_verify(EVP_PKEY_CTX *ctx,
|
||||
const unsigned char *sig, size_t siglen,
|
||||
const unsigned char *tbs, size_t tbslen)
|
||||
{
|
||||
int ret, type;
|
||||
EC_PKEY_CTX *dctx = ctx->data;
|
||||
EC_KEY *ec = ctx->pkey->pkey.ec;
|
||||
|
||||
if (dctx->md)
|
||||
type = EVP_MD_type(dctx->md);
|
||||
else
|
||||
type = NID_sha1;
|
||||
|
||||
ret = ECDSA_verify(type, tbs, tbslen, sig, siglen, ec);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_EC
|
||||
static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
|
||||
{
|
||||
int ret;
|
||||
size_t outlen;
|
||||
const EC_POINT *pubkey = NULL;
|
||||
EC_KEY *eckey;
|
||||
EC_PKEY_CTX *dctx = ctx->data;
|
||||
if (!ctx->pkey || !ctx->peerkey) {
|
||||
ECerr(EC_F_PKEY_EC_DERIVE, EC_R_KEYS_NOT_SET);
|
||||
return 0;
|
||||
}
|
||||
|
||||
eckey = dctx->co_key ? dctx->co_key : ctx->pkey->pkey.ec;
|
||||
|
||||
if (!key) {
|
||||
const EC_GROUP *group;
|
||||
group = EC_KEY_get0_group(eckey);
|
||||
*keylen = (EC_GROUP_get_degree(group) + 7) / 8;
|
||||
return 1;
|
||||
}
|
||||
pubkey = EC_KEY_get0_public_key(ctx->peerkey->pkey.ec);
|
||||
|
||||
/*
|
||||
* NB: unlike PKCS#3 DH, if *outlen is less than maximum size this is not
|
||||
* an error, the result is truncated.
|
||||
*/
|
||||
|
||||
outlen = *keylen;
|
||||
|
||||
ret = ECDH_compute_key(key, outlen, pubkey, eckey, 0);
|
||||
if (ret <= 0)
|
||||
return 0;
|
||||
*keylen = ret;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pkey_ec_kdf_derive(EVP_PKEY_CTX *ctx,
|
||||
unsigned char *key, size_t *keylen)
|
||||
{
|
||||
EC_PKEY_CTX *dctx = ctx->data;
|
||||
unsigned char *ktmp = NULL;
|
||||
size_t ktmplen;
|
||||
int rv = 0;
|
||||
if (dctx->kdf_type == EVP_PKEY_ECDH_KDF_NONE)
|
||||
return pkey_ec_derive(ctx, key, keylen);
|
||||
if (!key) {
|
||||
*keylen = dctx->kdf_outlen;
|
||||
return 1;
|
||||
}
|
||||
if (*keylen != dctx->kdf_outlen)
|
||||
return 0;
|
||||
if (!pkey_ec_derive(ctx, NULL, &ktmplen))
|
||||
return 0;
|
||||
if ((ktmp = OPENSSL_malloc(ktmplen)) == NULL) {
|
||||
ECerr(EC_F_PKEY_EC_KDF_DERIVE, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
if (!pkey_ec_derive(ctx, ktmp, &ktmplen))
|
||||
goto err;
|
||||
/* Do KDF stuff */
|
||||
if (!ecdh_KDF_X9_63(key, *keylen, ktmp, ktmplen,
|
||||
dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md))
|
||||
goto err;
|
||||
rv = 1;
|
||||
|
||||
err:
|
||||
OPENSSL_clear_free(ktmp, ktmplen);
|
||||
return rv;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
{
|
||||
EC_PKEY_CTX *dctx = ctx->data;
|
||||
EC_GROUP *group;
|
||||
switch (type) {
|
||||
case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID:
|
||||
group = EC_GROUP_new_by_curve_name(p1);
|
||||
if (group == NULL) {
|
||||
ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_CURVE);
|
||||
return 0;
|
||||
}
|
||||
EC_GROUP_free(dctx->gen_group);
|
||||
dctx->gen_group = group;
|
||||
return 1;
|
||||
|
||||
case EVP_PKEY_CTRL_EC_PARAM_ENC:
|
||||
if (!dctx->gen_group) {
|
||||
ECerr(EC_F_PKEY_EC_CTRL, EC_R_NO_PARAMETERS_SET);
|
||||
return 0;
|
||||
}
|
||||
EC_GROUP_set_asn1_flag(dctx->gen_group, p1);
|
||||
return 1;
|
||||
|
||||
#ifndef OPENSSL_NO_EC
|
||||
case EVP_PKEY_CTRL_EC_ECDH_COFACTOR:
|
||||
if (p1 == -2) {
|
||||
if (dctx->cofactor_mode != -1)
|
||||
return dctx->cofactor_mode;
|
||||
else {
|
||||
EC_KEY *ec_key = ctx->pkey->pkey.ec;
|
||||
return EC_KEY_get_flags(ec_key) & EC_FLAG_COFACTOR_ECDH ? 1 : 0;
|
||||
}
|
||||
} else if (p1 < -1 || p1 > 1)
|
||||
return -2;
|
||||
dctx->cofactor_mode = p1;
|
||||
if (p1 != -1) {
|
||||
EC_KEY *ec_key = ctx->pkey->pkey.ec;
|
||||
if (!ec_key->group)
|
||||
return -2;
|
||||
/* If cofactor is 1 cofactor mode does nothing */
|
||||
if (BN_is_one(ec_key->group->cofactor))
|
||||
return 1;
|
||||
if (!dctx->co_key) {
|
||||
dctx->co_key = EC_KEY_dup(ec_key);
|
||||
if (!dctx->co_key)
|
||||
return 0;
|
||||
}
|
||||
if (p1)
|
||||
EC_KEY_set_flags(dctx->co_key, EC_FLAG_COFACTOR_ECDH);
|
||||
else
|
||||
EC_KEY_clear_flags(dctx->co_key, EC_FLAG_COFACTOR_ECDH);
|
||||
} else {
|
||||
EC_KEY_free(dctx->co_key);
|
||||
dctx->co_key = NULL;
|
||||
}
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
case EVP_PKEY_CTRL_EC_KDF_TYPE:
|
||||
if (p1 == -2)
|
||||
return dctx->kdf_type;
|
||||
if (p1 != EVP_PKEY_ECDH_KDF_NONE && p1 != EVP_PKEY_ECDH_KDF_X9_63)
|
||||
return -2;
|
||||
dctx->kdf_type = p1;
|
||||
return 1;
|
||||
|
||||
case EVP_PKEY_CTRL_EC_KDF_MD:
|
||||
dctx->kdf_md = p2;
|
||||
return 1;
|
||||
|
||||
case EVP_PKEY_CTRL_GET_EC_KDF_MD:
|
||||
*(const EVP_MD **)p2 = dctx->kdf_md;
|
||||
return 1;
|
||||
|
||||
case EVP_PKEY_CTRL_EC_KDF_OUTLEN:
|
||||
if (p1 <= 0)
|
||||
return -2;
|
||||
dctx->kdf_outlen = (size_t)p1;
|
||||
return 1;
|
||||
|
||||
case EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN:
|
||||
*(int *)p2 = dctx->kdf_outlen;
|
||||
return 1;
|
||||
|
||||
case EVP_PKEY_CTRL_EC_KDF_UKM:
|
||||
OPENSSL_free(dctx->kdf_ukm);
|
||||
dctx->kdf_ukm = p2;
|
||||
if (p2)
|
||||
dctx->kdf_ukmlen = p1;
|
||||
else
|
||||
dctx->kdf_ukmlen = 0;
|
||||
return 1;
|
||||
|
||||
case EVP_PKEY_CTRL_GET_EC_KDF_UKM:
|
||||
*(unsigned char **)p2 = dctx->kdf_ukm;
|
||||
return dctx->kdf_ukmlen;
|
||||
|
||||
case EVP_PKEY_CTRL_MD:
|
||||
if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 &&
|
||||
EVP_MD_type((const EVP_MD *)p2) != NID_ecdsa_with_SHA1 &&
|
||||
EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
|
||||
EVP_MD_type((const EVP_MD *)p2) != NID_sha256 &&
|
||||
EVP_MD_type((const EVP_MD *)p2) != NID_sha384 &&
|
||||
EVP_MD_type((const EVP_MD *)p2) != NID_sha512) {
|
||||
ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE);
|
||||
return 0;
|
||||
}
|
||||
dctx->md = p2;
|
||||
return 1;
|
||||
|
||||
case EVP_PKEY_CTRL_GET_MD:
|
||||
*(const EVP_MD **)p2 = dctx->md;
|
||||
return 1;
|
||||
|
||||
case EVP_PKEY_CTRL_PEER_KEY:
|
||||
/* Default behaviour is OK */
|
||||
case EVP_PKEY_CTRL_DIGESTINIT:
|
||||
case EVP_PKEY_CTRL_PKCS7_SIGN:
|
||||
case EVP_PKEY_CTRL_CMS_SIGN:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return -2;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static int pkey_ec_ctrl_str(EVP_PKEY_CTX *ctx,
|
||||
const char *type, const char *value)
|
||||
{
|
||||
if (strcmp(type, "ec_paramgen_curve") == 0) {
|
||||
int nid;
|
||||
nid = EC_curve_nist2nid(value);
|
||||
if (nid == NID_undef)
|
||||
nid = OBJ_sn2nid(value);
|
||||
if (nid == NID_undef)
|
||||
nid = OBJ_ln2nid(value);
|
||||
if (nid == NID_undef) {
|
||||
ECerr(EC_F_PKEY_EC_CTRL_STR, EC_R_INVALID_CURVE);
|
||||
return 0;
|
||||
}
|
||||
return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid);
|
||||
} else if (strcmp(type, "ec_param_enc") == 0) {
|
||||
int param_enc;
|
||||
if (strcmp(value, "explicit") == 0)
|
||||
param_enc = 0;
|
||||
else if (strcmp(value, "named_curve") == 0)
|
||||
param_enc = OPENSSL_EC_NAMED_CURVE;
|
||||
else
|
||||
return -2;
|
||||
return EVP_PKEY_CTX_set_ec_param_enc(ctx, param_enc);
|
||||
} else if (strcmp(type, "ecdh_kdf_md") == 0) {
|
||||
const EVP_MD *md;
|
||||
if ((md = EVP_get_digestbyname(value)) == NULL) {
|
||||
ECerr(EC_F_PKEY_EC_CTRL_STR, EC_R_INVALID_DIGEST);
|
||||
return 0;
|
||||
}
|
||||
return EVP_PKEY_CTX_set_ecdh_kdf_md(ctx, md);
|
||||
} else if (strcmp(type, "ecdh_cofactor_mode") == 0) {
|
||||
int co_mode;
|
||||
co_mode = atoi(value);
|
||||
return EVP_PKEY_CTX_set_ecdh_cofactor_mode(ctx, co_mode);
|
||||
}
|
||||
|
||||
return -2;
|
||||
}
|
||||
|
||||
static int pkey_ec_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
|
||||
{
|
||||
EC_KEY *ec = NULL;
|
||||
EC_PKEY_CTX *dctx = ctx->data;
|
||||
int ret;
|
||||
|
||||
if (dctx->gen_group == NULL) {
|
||||
ECerr(EC_F_PKEY_EC_PARAMGEN, EC_R_NO_PARAMETERS_SET);
|
||||
return 0;
|
||||
}
|
||||
ec = EC_KEY_new();
|
||||
if (ec == NULL)
|
||||
return 0;
|
||||
if (!(ret = EC_KEY_set_group(ec, dctx->gen_group))
|
||||
|| !ossl_assert(ret = EVP_PKEY_assign_EC_KEY(pkey, ec)))
|
||||
EC_KEY_free(ec);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
|
||||
{
|
||||
EC_KEY *ec = NULL;
|
||||
EC_PKEY_CTX *dctx = ctx->data;
|
||||
int ret;
|
||||
|
||||
if (ctx->pkey == NULL && dctx->gen_group == NULL) {
|
||||
ECerr(EC_F_PKEY_EC_KEYGEN, EC_R_NO_PARAMETERS_SET);
|
||||
return 0;
|
||||
}
|
||||
ec = EC_KEY_new();
|
||||
if (ec == NULL)
|
||||
return 0;
|
||||
if (!ossl_assert(EVP_PKEY_assign_EC_KEY(pkey, ec))) {
|
||||
EC_KEY_free(ec);
|
||||
return 0;
|
||||
}
|
||||
/* Note: if error is returned, we count on caller to free pkey->pkey.ec */
|
||||
if (ctx->pkey != NULL)
|
||||
ret = EVP_PKEY_copy_parameters(pkey, ctx->pkey);
|
||||
else
|
||||
ret = EC_KEY_set_group(ec, dctx->gen_group);
|
||||
|
||||
return ret ? EC_KEY_generate_key(ec) : 0;
|
||||
}
|
||||
|
||||
const EVP_PKEY_METHOD ec_pkey_meth = {
|
||||
EVP_PKEY_EC,
|
||||
0,
|
||||
pkey_ec_init,
|
||||
pkey_ec_copy,
|
||||
pkey_ec_cleanup,
|
||||
|
||||
0,
|
||||
pkey_ec_paramgen,
|
||||
|
||||
0,
|
||||
pkey_ec_keygen,
|
||||
|
||||
0,
|
||||
pkey_ec_sign,
|
||||
|
||||
0,
|
||||
pkey_ec_verify,
|
||||
|
||||
0, 0,
|
||||
|
||||
0, 0, 0, 0,
|
||||
|
||||
0,
|
||||
0,
|
||||
|
||||
0,
|
||||
0,
|
||||
|
||||
0,
|
||||
#ifndef OPENSSL_NO_EC
|
||||
pkey_ec_kdf_derive,
|
||||
#else
|
||||
0,
|
||||
#endif
|
||||
pkey_ec_ctrl,
|
||||
pkey_ec_ctrl_str
|
||||
};
|
121
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ec_print.c
vendored
Normal file
121
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ec_print.c
vendored
Normal file
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/err.h>
|
||||
#include "ec_lcl.h"
|
||||
|
||||
BIGNUM *EC_POINT_point2bn(const EC_GROUP *group,
|
||||
const EC_POINT *point,
|
||||
point_conversion_form_t form,
|
||||
BIGNUM *ret, BN_CTX *ctx)
|
||||
{
|
||||
size_t buf_len = 0;
|
||||
unsigned char *buf;
|
||||
|
||||
buf_len = EC_POINT_point2buf(group, point, form, &buf, ctx);
|
||||
|
||||
if (buf_len == 0)
|
||||
return NULL;
|
||||
|
||||
ret = BN_bin2bn(buf, buf_len, ret);
|
||||
|
||||
OPENSSL_free(buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
EC_POINT *EC_POINT_bn2point(const EC_GROUP *group,
|
||||
const BIGNUM *bn, EC_POINT *point, BN_CTX *ctx)
|
||||
{
|
||||
size_t buf_len = 0;
|
||||
unsigned char *buf;
|
||||
EC_POINT *ret;
|
||||
|
||||
if ((buf_len = BN_num_bytes(bn)) == 0)
|
||||
return NULL;
|
||||
if ((buf = OPENSSL_malloc(buf_len)) == NULL) {
|
||||
ECerr(EC_F_EC_POINT_BN2POINT, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!BN_bn2bin(bn, buf)) {
|
||||
OPENSSL_free(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (point == NULL) {
|
||||
if ((ret = EC_POINT_new(group)) == NULL) {
|
||||
OPENSSL_free(buf);
|
||||
return NULL;
|
||||
}
|
||||
} else
|
||||
ret = point;
|
||||
|
||||
if (!EC_POINT_oct2point(group, ret, buf, buf_len, ctx)) {
|
||||
if (ret != point)
|
||||
EC_POINT_clear_free(ret);
|
||||
OPENSSL_free(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
OPENSSL_free(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const char *HEX_DIGITS = "0123456789ABCDEF";
|
||||
|
||||
/* the return value must be freed (using OPENSSL_free()) */
|
||||
char *EC_POINT_point2hex(const EC_GROUP *group,
|
||||
const EC_POINT *point,
|
||||
point_conversion_form_t form, BN_CTX *ctx)
|
||||
{
|
||||
char *ret, *p;
|
||||
size_t buf_len = 0, i;
|
||||
unsigned char *buf = NULL, *pbuf;
|
||||
|
||||
buf_len = EC_POINT_point2buf(group, point, form, &buf, ctx);
|
||||
|
||||
if (buf_len == 0)
|
||||
return NULL;
|
||||
|
||||
ret = OPENSSL_malloc(buf_len * 2 + 2);
|
||||
if (ret == NULL) {
|
||||
OPENSSL_free(buf);
|
||||
return NULL;
|
||||
}
|
||||
p = ret;
|
||||
pbuf = buf;
|
||||
for (i = buf_len; i > 0; i--) {
|
||||
int v = (int)*(pbuf++);
|
||||
*(p++) = HEX_DIGITS[v >> 4];
|
||||
*(p++) = HEX_DIGITS[v & 0x0F];
|
||||
}
|
||||
*p = '\0';
|
||||
|
||||
OPENSSL_free(buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
EC_POINT *EC_POINT_hex2point(const EC_GROUP *group,
|
||||
const char *buf, EC_POINT *point, BN_CTX *ctx)
|
||||
{
|
||||
EC_POINT *ret = NULL;
|
||||
BIGNUM *tmp_bn = NULL;
|
||||
|
||||
if (!BN_hex2bn(&tmp_bn, buf))
|
||||
return NULL;
|
||||
|
||||
ret = EC_POINT_bn2point(group, tmp_bn, point, ctx);
|
||||
|
||||
BN_clear_free(tmp_bn);
|
||||
|
||||
return ret;
|
||||
}
|
81
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ecdh_kdf.c
vendored
Normal file
81
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ecdh_kdf.c
vendored
Normal file
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/evp.h>
|
||||
#include "ec_lcl.h"
|
||||
|
||||
/* Key derivation function from X9.63/SECG */
|
||||
/* Way more than we will ever need */
|
||||
#define ECDH_KDF_MAX (1 << 30)
|
||||
|
||||
int ecdh_KDF_X9_63(unsigned char *out, size_t outlen,
|
||||
const unsigned char *Z, size_t Zlen,
|
||||
const unsigned char *sinfo, size_t sinfolen,
|
||||
const EVP_MD *md)
|
||||
{
|
||||
EVP_MD_CTX *mctx = NULL;
|
||||
int rv = 0;
|
||||
unsigned int i;
|
||||
size_t mdlen;
|
||||
unsigned char ctr[4];
|
||||
if (sinfolen > ECDH_KDF_MAX || outlen > ECDH_KDF_MAX
|
||||
|| Zlen > ECDH_KDF_MAX)
|
||||
return 0;
|
||||
mctx = EVP_MD_CTX_new();
|
||||
if (mctx == NULL)
|
||||
return 0;
|
||||
mdlen = EVP_MD_size(md);
|
||||
for (i = 1;; i++) {
|
||||
unsigned char mtmp[EVP_MAX_MD_SIZE];
|
||||
if (!EVP_DigestInit_ex(mctx, md, NULL))
|
||||
goto err;
|
||||
ctr[3] = i & 0xFF;
|
||||
ctr[2] = (i >> 8) & 0xFF;
|
||||
ctr[1] = (i >> 16) & 0xFF;
|
||||
ctr[0] = (i >> 24) & 0xFF;
|
||||
if (!EVP_DigestUpdate(mctx, Z, Zlen))
|
||||
goto err;
|
||||
if (!EVP_DigestUpdate(mctx, ctr, sizeof(ctr)))
|
||||
goto err;
|
||||
if (!EVP_DigestUpdate(mctx, sinfo, sinfolen))
|
||||
goto err;
|
||||
if (outlen >= mdlen) {
|
||||
if (!EVP_DigestFinal(mctx, out, NULL))
|
||||
goto err;
|
||||
outlen -= mdlen;
|
||||
if (outlen == 0)
|
||||
break;
|
||||
out += mdlen;
|
||||
} else {
|
||||
if (!EVP_DigestFinal(mctx, mtmp, NULL))
|
||||
goto err;
|
||||
memcpy(out, mtmp, outlen);
|
||||
OPENSSL_cleanse(mtmp, mdlen);
|
||||
break;
|
||||
}
|
||||
}
|
||||
rv = 1;
|
||||
err:
|
||||
EVP_MD_CTX_free(mctx);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*-
|
||||
* The old name for ecdh_KDF_X9_63
|
||||
* Retained for ABI compatibility
|
||||
*/
|
||||
int ECDH_KDF_X9_62(unsigned char *out, size_t outlen,
|
||||
const unsigned char *Z, size_t Zlen,
|
||||
const unsigned char *sinfo, size_t sinfolen,
|
||||
const EVP_MD *md)
|
||||
{
|
||||
return ecdh_KDF_X9_63(out, outlen, Z, Zlen, sinfo, sinfolen, md);
|
||||
}
|
121
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ecdh_ossl.c
vendored
Normal file
121
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ecdh_ossl.c
vendored
Normal file
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* Copyright 2002-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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "internal/cryptlib.h"
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/ec.h>
|
||||
#include "ec_lcl.h"
|
||||
|
||||
int ossl_ecdh_compute_key(unsigned char **psec, size_t *pseclen,
|
||||
const EC_POINT *pub_key, const EC_KEY *ecdh)
|
||||
{
|
||||
if (ecdh->group->meth->ecdh_compute_key == NULL) {
|
||||
ECerr(EC_F_OSSL_ECDH_COMPUTE_KEY, EC_R_CURVE_DOES_NOT_SUPPORT_ECDH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ecdh->group->meth->ecdh_compute_key(psec, pseclen, pub_key, ecdh);
|
||||
}
|
||||
|
||||
/*-
|
||||
* This implementation is based on the following primitives in the IEEE 1363 standard:
|
||||
* - ECKAS-DH1
|
||||
* - ECSVDP-DH
|
||||
*/
|
||||
int ecdh_simple_compute_key(unsigned char **pout, size_t *poutlen,
|
||||
const EC_POINT *pub_key, const EC_KEY *ecdh)
|
||||
{
|
||||
BN_CTX *ctx;
|
||||
EC_POINT *tmp = NULL;
|
||||
BIGNUM *x = NULL;
|
||||
const BIGNUM *priv_key;
|
||||
const EC_GROUP *group;
|
||||
int ret = 0;
|
||||
size_t buflen, len;
|
||||
unsigned char *buf = NULL;
|
||||
|
||||
if ((ctx = BN_CTX_new()) == NULL)
|
||||
goto err;
|
||||
BN_CTX_start(ctx);
|
||||
x = BN_CTX_get(ctx);
|
||||
if (x == NULL) {
|
||||
ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
priv_key = EC_KEY_get0_private_key(ecdh);
|
||||
if (priv_key == NULL) {
|
||||
ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, EC_R_NO_PRIVATE_VALUE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
group = EC_KEY_get0_group(ecdh);
|
||||
|
||||
if (EC_KEY_get_flags(ecdh) & EC_FLAG_COFACTOR_ECDH) {
|
||||
if (!EC_GROUP_get_cofactor(group, x, NULL) ||
|
||||
!BN_mul(x, x, priv_key, ctx)) {
|
||||
ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
priv_key = x;
|
||||
}
|
||||
|
||||
if ((tmp = EC_POINT_new(group)) == NULL) {
|
||||
ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!EC_POINT_mul(group, tmp, NULL, pub_key, priv_key, ctx)) {
|
||||
ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, EC_R_POINT_ARITHMETIC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!EC_POINT_get_affine_coordinates(group, tmp, x, NULL, ctx)) {
|
||||
ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, EC_R_POINT_ARITHMETIC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
buflen = (EC_GROUP_get_degree(group) + 7) / 8;
|
||||
len = BN_num_bytes(x);
|
||||
if (len > buflen) {
|
||||
ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
if ((buf = OPENSSL_malloc(buflen)) == NULL) {
|
||||
ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
memset(buf, 0, buflen - len);
|
||||
if (len != (size_t)BN_bn2bin(x, buf + buflen - len)) {
|
||||
ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
|
||||
*pout = buf;
|
||||
*poutlen = buflen;
|
||||
buf = NULL;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
EC_POINT_free(tmp);
|
||||
if (ctx)
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
OPENSSL_free(buf);
|
||||
return ret;
|
||||
}
|
417
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ecdsa_ossl.c
vendored
Normal file
417
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ecdsa_ossl.c
vendored
Normal file
|
@ -0,0 +1,417 @@
|
|||
/*
|
||||
* 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/obj_mac.h>
|
||||
#include <openssl/rand.h>
|
||||
#include "internal/bn_int.h"
|
||||
#include "ec_lcl.h"
|
||||
|
||||
int ossl_ecdsa_sign(int type, const unsigned char *dgst, int dlen,
|
||||
unsigned char *sig, unsigned int *siglen,
|
||||
const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey)
|
||||
{
|
||||
ECDSA_SIG *s;
|
||||
|
||||
s = ECDSA_do_sign_ex(dgst, dlen, kinv, r, eckey);
|
||||
if (s == NULL) {
|
||||
*siglen = 0;
|
||||
return 0;
|
||||
}
|
||||
*siglen = i2d_ECDSA_SIG(s, &sig);
|
||||
ECDSA_SIG_free(s);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in,
|
||||
BIGNUM **kinvp, BIGNUM **rp,
|
||||
const unsigned char *dgst, int dlen)
|
||||
{
|
||||
BN_CTX *ctx = NULL;
|
||||
BIGNUM *k = NULL, *r = NULL, *X = NULL;
|
||||
const BIGNUM *order;
|
||||
EC_POINT *tmp_point = NULL;
|
||||
const EC_GROUP *group;
|
||||
int ret = 0;
|
||||
int order_bits;
|
||||
|
||||
if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) {
|
||||
ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!EC_KEY_can_sign(eckey)) {
|
||||
ECerr(EC_F_ECDSA_SIGN_SETUP, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((ctx = ctx_in) == NULL) {
|
||||
if ((ctx = BN_CTX_new()) == NULL) {
|
||||
ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
k = BN_new(); /* this value is later returned in *kinvp */
|
||||
r = BN_new(); /* this value is later returned in *rp */
|
||||
X = BN_new();
|
||||
if (k == NULL || r == NULL || X == NULL) {
|
||||
ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
if ((tmp_point = EC_POINT_new(group)) == NULL) {
|
||||
ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
order = EC_GROUP_get0_order(group);
|
||||
|
||||
/* Preallocate space */
|
||||
order_bits = BN_num_bits(order);
|
||||
if (!BN_set_bit(k, order_bits)
|
||||
|| !BN_set_bit(r, order_bits)
|
||||
|| !BN_set_bit(X, order_bits))
|
||||
goto err;
|
||||
|
||||
do {
|
||||
/* get random k */
|
||||
do {
|
||||
if (dgst != NULL) {
|
||||
if (!BN_generate_dsa_nonce(k, order,
|
||||
EC_KEY_get0_private_key(eckey),
|
||||
dgst, dlen, ctx)) {
|
||||
ECerr(EC_F_ECDSA_SIGN_SETUP,
|
||||
EC_R_RANDOM_NUMBER_GENERATION_FAILED);
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
if (!BN_priv_rand_range(k, order)) {
|
||||
ECerr(EC_F_ECDSA_SIGN_SETUP,
|
||||
EC_R_RANDOM_NUMBER_GENERATION_FAILED);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
} while (BN_is_zero(k));
|
||||
|
||||
/* compute r the x-coordinate of generator * k */
|
||||
if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) {
|
||||
ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!EC_POINT_get_affine_coordinates(group, tmp_point, X, NULL, ctx)) {
|
||||
ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!BN_nnmod(r, X, order, ctx)) {
|
||||
ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
} while (BN_is_zero(r));
|
||||
|
||||
/* compute the inverse of k */
|
||||
if (!ec_group_do_inverse_ord(group, k, k, ctx)) {
|
||||
ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* clear old values if necessary */
|
||||
BN_clear_free(*rp);
|
||||
BN_clear_free(*kinvp);
|
||||
/* save the pre-computed values */
|
||||
*rp = r;
|
||||
*kinvp = k;
|
||||
ret = 1;
|
||||
err:
|
||||
if (!ret) {
|
||||
BN_clear_free(k);
|
||||
BN_clear_free(r);
|
||||
}
|
||||
if (ctx != ctx_in)
|
||||
BN_CTX_free(ctx);
|
||||
EC_POINT_free(tmp_point);
|
||||
BN_clear_free(X);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ossl_ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
|
||||
BIGNUM **rp)
|
||||
{
|
||||
return ecdsa_sign_setup(eckey, ctx_in, kinvp, rp, NULL, 0);
|
||||
}
|
||||
|
||||
ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len,
|
||||
const BIGNUM *in_kinv, const BIGNUM *in_r,
|
||||
EC_KEY *eckey)
|
||||
{
|
||||
int ok = 0, i;
|
||||
BIGNUM *kinv = NULL, *s, *m = NULL;
|
||||
const BIGNUM *order, *ckinv;
|
||||
BN_CTX *ctx = NULL;
|
||||
const EC_GROUP *group;
|
||||
ECDSA_SIG *ret;
|
||||
const BIGNUM *priv_key;
|
||||
|
||||
group = EC_KEY_get0_group(eckey);
|
||||
priv_key = EC_KEY_get0_private_key(eckey);
|
||||
|
||||
if (group == NULL || priv_key == NULL) {
|
||||
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!EC_KEY_can_sign(eckey)) {
|
||||
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = ECDSA_SIG_new();
|
||||
if (ret == NULL) {
|
||||
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
ret->r = BN_new();
|
||||
ret->s = BN_new();
|
||||
if (ret->r == NULL || ret->s == NULL) {
|
||||
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
s = ret->s;
|
||||
|
||||
if ((ctx = BN_CTX_new()) == NULL
|
||||
|| (m = BN_new()) == NULL) {
|
||||
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
order = EC_GROUP_get0_order(group);
|
||||
i = BN_num_bits(order);
|
||||
/*
|
||||
* Need to truncate digest if it is too long: first truncate whole bytes.
|
||||
*/
|
||||
if (8 * dgst_len > i)
|
||||
dgst_len = (i + 7) / 8;
|
||||
if (!BN_bin2bn(dgst, dgst_len, m)) {
|
||||
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
/* If still too long, truncate remaining bits with a shift */
|
||||
if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) {
|
||||
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
do {
|
||||
if (in_kinv == NULL || in_r == NULL) {
|
||||
if (!ecdsa_sign_setup(eckey, ctx, &kinv, &ret->r, dgst, dgst_len)) {
|
||||
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_ECDSA_LIB);
|
||||
goto err;
|
||||
}
|
||||
ckinv = kinv;
|
||||
} else {
|
||||
ckinv = in_kinv;
|
||||
if (BN_copy(ret->r, in_r) == NULL) {
|
||||
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* With only one multiplicant being in Montgomery domain
|
||||
* multiplication yields real result without post-conversion.
|
||||
* Also note that all operations but last are performed with
|
||||
* zero-padded vectors. Last operation, BN_mod_mul_montgomery
|
||||
* below, returns user-visible value with removed zero padding.
|
||||
*/
|
||||
if (!bn_to_mont_fixed_top(s, ret->r, group->mont_data, ctx)
|
||||
|| !bn_mul_mont_fixed_top(s, s, priv_key, group->mont_data, ctx)) {
|
||||
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
if (!bn_mod_add_fixed_top(s, s, m, order)) {
|
||||
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
/*
|
||||
* |s| can still be larger than modulus, because |m| can be. In
|
||||
* such case we count on Montgomery reduction to tie it up.
|
||||
*/
|
||||
if (!bn_to_mont_fixed_top(s, s, group->mont_data, ctx)
|
||||
|| !BN_mod_mul_montgomery(s, s, ckinv, group->mont_data, ctx)) {
|
||||
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (BN_is_zero(s)) {
|
||||
/*
|
||||
* 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) {
|
||||
ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, EC_R_NEED_NEW_SETUP_VALUES);
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
/* s != 0 => we have a valid signature */
|
||||
break;
|
||||
}
|
||||
} while (1);
|
||||
|
||||
ok = 1;
|
||||
err:
|
||||
if (!ok) {
|
||||
ECDSA_SIG_free(ret);
|
||||
ret = NULL;
|
||||
}
|
||||
BN_CTX_free(ctx);
|
||||
BN_clear_free(m);
|
||||
BN_clear_free(kinv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*-
|
||||
* returns
|
||||
* 1: correct signature
|
||||
* 0: incorrect signature
|
||||
* -1: error
|
||||
*/
|
||||
int ossl_ecdsa_verify(int type, const unsigned char *dgst, int dgst_len,
|
||||
const unsigned char *sigbuf, int sig_len, EC_KEY *eckey)
|
||||
{
|
||||
ECDSA_SIG *s;
|
||||
const unsigned char *p = sigbuf;
|
||||
unsigned char *der = NULL;
|
||||
int derlen = -1;
|
||||
int ret = -1;
|
||||
|
||||
s = ECDSA_SIG_new();
|
||||
if (s == NULL)
|
||||
return ret;
|
||||
if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL)
|
||||
goto err;
|
||||
/* Ensure signature uses DER and doesn't have trailing garbage */
|
||||
derlen = i2d_ECDSA_SIG(s, &der);
|
||||
if (derlen != sig_len || memcmp(sigbuf, der, derlen) != 0)
|
||||
goto err;
|
||||
ret = ECDSA_do_verify(dgst, dgst_len, s, eckey);
|
||||
err:
|
||||
OPENSSL_clear_free(der, derlen);
|
||||
ECDSA_SIG_free(s);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ossl_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len,
|
||||
const ECDSA_SIG *sig, EC_KEY *eckey)
|
||||
{
|
||||
int ret = -1, i;
|
||||
BN_CTX *ctx;
|
||||
const BIGNUM *order;
|
||||
BIGNUM *u1, *u2, *m, *X;
|
||||
EC_POINT *point = NULL;
|
||||
const EC_GROUP *group;
|
||||
const EC_POINT *pub_key;
|
||||
|
||||
/* check input values */
|
||||
if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL ||
|
||||
(pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL) {
|
||||
ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, EC_R_MISSING_PARAMETERS);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!EC_KEY_can_sign(eckey)) {
|
||||
ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ctx = BN_CTX_new();
|
||||
if (ctx == NULL) {
|
||||
ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_MALLOC_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
BN_CTX_start(ctx);
|
||||
u1 = BN_CTX_get(ctx);
|
||||
u2 = BN_CTX_get(ctx);
|
||||
m = BN_CTX_get(ctx);
|
||||
X = BN_CTX_get(ctx);
|
||||
if (X == NULL) {
|
||||
ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
|
||||
order = EC_GROUP_get0_order(group);
|
||||
if (order == NULL) {
|
||||
ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (BN_is_zero(sig->r) || BN_is_negative(sig->r) ||
|
||||
BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s) ||
|
||||
BN_is_negative(sig->s) || BN_ucmp(sig->s, order) >= 0) {
|
||||
ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, EC_R_BAD_SIGNATURE);
|
||||
ret = 0; /* signature is invalid */
|
||||
goto err;
|
||||
}
|
||||
/* calculate tmp1 = inv(S) mod order */
|
||||
if (!ec_group_do_inverse_ord(group, u2, sig->s, ctx)) {
|
||||
ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
/* digest -> m */
|
||||
i = BN_num_bits(order);
|
||||
/*
|
||||
* Need to truncate digest if it is too long: first truncate whole bytes.
|
||||
*/
|
||||
if (8 * dgst_len > i)
|
||||
dgst_len = (i + 7) / 8;
|
||||
if (!BN_bin2bn(dgst, dgst_len, m)) {
|
||||
ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
/* If still too long truncate remaining bits with a shift */
|
||||
if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) {
|
||||
ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
/* u1 = m * tmp mod order */
|
||||
if (!BN_mod_mul(u1, m, u2, order, ctx)) {
|
||||
ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
/* u2 = r * w mod q */
|
||||
if (!BN_mod_mul(u2, sig->r, u2, order, ctx)) {
|
||||
ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((point = EC_POINT_new(group)) == NULL) {
|
||||
ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx)) {
|
||||
ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!EC_POINT_get_affine_coordinates(group, point, X, NULL, ctx)) {
|
||||
ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!BN_nnmod(u1, X, order, ctx)) {
|
||||
ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
/* if the signature is correct u1 is equal to sig->r */
|
||||
ret = (BN_ucmp(u1, sig->r) == 0);
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
EC_POINT_free(point);
|
||||
return ret;
|
||||
}
|
52
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ecdsa_sign.c
vendored
Normal file
52
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ecdsa_sign.c
vendored
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright 2015-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
|
||||
*/
|
||||
|
||||
#include <openssl/ec.h>
|
||||
#include "ec_lcl.h"
|
||||
#include <openssl/err.h>
|
||||
|
||||
ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey)
|
||||
{
|
||||
return ECDSA_do_sign_ex(dgst, dlen, NULL, NULL, eckey);
|
||||
}
|
||||
|
||||
ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dlen,
|
||||
const BIGNUM *kinv, const BIGNUM *rp,
|
||||
EC_KEY *eckey)
|
||||
{
|
||||
if (eckey->meth->sign_sig != NULL)
|
||||
return eckey->meth->sign_sig(dgst, dlen, kinv, rp, eckey);
|
||||
ECerr(EC_F_ECDSA_DO_SIGN_EX, EC_R_OPERATION_NOT_SUPPORTED);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int ECDSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char
|
||||
*sig, unsigned int *siglen, EC_KEY *eckey)
|
||||
{
|
||||
return ECDSA_sign_ex(type, dgst, dlen, sig, siglen, NULL, NULL, eckey);
|
||||
}
|
||||
|
||||
int ECDSA_sign_ex(int type, const unsigned char *dgst, int dlen,
|
||||
unsigned char *sig, unsigned int *siglen, const BIGNUM *kinv,
|
||||
const BIGNUM *r, EC_KEY *eckey)
|
||||
{
|
||||
if (eckey->meth->sign != NULL)
|
||||
return eckey->meth->sign(type, dgst, dlen, sig, siglen, kinv, r, eckey);
|
||||
ECerr(EC_F_ECDSA_SIGN_EX, EC_R_OPERATION_NOT_SUPPORTED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
|
||||
BIGNUM **rp)
|
||||
{
|
||||
if (eckey->meth->sign_setup != NULL)
|
||||
return eckey->meth->sign_setup(eckey, ctx_in, kinvp, rp);
|
||||
ECerr(EC_F_ECDSA_SIGN_SETUP, EC_R_OPERATION_NOT_SUPPORTED);
|
||||
return 0;
|
||||
}
|
43
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ecdsa_vrf.c
vendored
Normal file
43
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ecdsa_vrf.c
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright 2002-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
|
||||
*/
|
||||
|
||||
#include <openssl/ec.h>
|
||||
#include "ec_lcl.h"
|
||||
#include <openssl/err.h>
|
||||
|
||||
/*-
|
||||
* returns
|
||||
* 1: correct signature
|
||||
* 0: incorrect signature
|
||||
* -1: error
|
||||
*/
|
||||
int ECDSA_do_verify(const unsigned char *dgst, int dgst_len,
|
||||
const ECDSA_SIG *sig, EC_KEY *eckey)
|
||||
{
|
||||
if (eckey->meth->verify_sig != NULL)
|
||||
return eckey->meth->verify_sig(dgst, dgst_len, sig, eckey);
|
||||
ECerr(EC_F_ECDSA_DO_VERIFY, EC_R_OPERATION_NOT_SUPPORTED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-
|
||||
* returns
|
||||
* 1: correct signature
|
||||
* 0: incorrect signature
|
||||
* -1: error
|
||||
*/
|
||||
int ECDSA_verify(int type, const unsigned char *dgst, int dgst_len,
|
||||
const unsigned char *sigbuf, int sig_len, EC_KEY *eckey)
|
||||
{
|
||||
if (eckey->meth->verify != NULL)
|
||||
return eckey->meth->verify(type, dgst, dgst_len, sigbuf, sig_len,
|
||||
eckey);
|
||||
ECerr(EC_F_ECDSA_VERIFY, EC_R_OPERATION_NOT_SUPPORTED);
|
||||
return 0;
|
||||
}
|
259
trunk/3rdparty/openssl-1.1-fit/crypto/ec/eck_prn.c
vendored
Normal file
259
trunk/3rdparty/openssl-1.1-fit/crypto/ec/eck_prn.c
vendored
Normal file
|
@ -0,0 +1,259 @@
|
|||
/*
|
||||
* Copyright 2006-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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#ifndef OPENSSL_NO_STDIO
|
||||
int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off)
|
||||
{
|
||||
BIO *b;
|
||||
int ret;
|
||||
|
||||
if ((b = BIO_new(BIO_s_file())) == NULL) {
|
||||
ECerr(EC_F_ECPKPARAMETERS_PRINT_FP, ERR_R_BUF_LIB);
|
||||
return 0;
|
||||
}
|
||||
BIO_set_fp(b, fp, BIO_NOCLOSE);
|
||||
ret = ECPKParameters_print(b, x, off);
|
||||
BIO_free(b);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off)
|
||||
{
|
||||
BIO *b;
|
||||
int ret;
|
||||
|
||||
if ((b = BIO_new(BIO_s_file())) == NULL) {
|
||||
ECerr(EC_F_EC_KEY_PRINT_FP, ERR_R_BIO_LIB);
|
||||
return 0;
|
||||
}
|
||||
BIO_set_fp(b, fp, BIO_NOCLOSE);
|
||||
ret = EC_KEY_print(b, x, off);
|
||||
BIO_free(b);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ECParameters_print_fp(FILE *fp, const EC_KEY *x)
|
||||
{
|
||||
BIO *b;
|
||||
int ret;
|
||||
|
||||
if ((b = BIO_new(BIO_s_file())) == NULL) {
|
||||
ECerr(EC_F_ECPARAMETERS_PRINT_FP, ERR_R_BIO_LIB);
|
||||
return 0;
|
||||
}
|
||||
BIO_set_fp(b, fp, BIO_NOCLOSE);
|
||||
ret = ECParameters_print(b, x);
|
||||
BIO_free(b);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int print_bin(BIO *fp, const char *str, const unsigned char *num,
|
||||
size_t len, int off);
|
||||
|
||||
int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off)
|
||||
{
|
||||
int ret = 0, reason = ERR_R_BIO_LIB;
|
||||
BN_CTX *ctx = NULL;
|
||||
const EC_POINT *point = NULL;
|
||||
BIGNUM *p = NULL, *a = NULL, *b = NULL, *gen = NULL;
|
||||
const BIGNUM *order = NULL, *cofactor = NULL;
|
||||
const unsigned char *seed;
|
||||
size_t seed_len = 0;
|
||||
|
||||
static const char *gen_compressed = "Generator (compressed):";
|
||||
static const char *gen_uncompressed = "Generator (uncompressed):";
|
||||
static const char *gen_hybrid = "Generator (hybrid):";
|
||||
|
||||
if (!x) {
|
||||
reason = ERR_R_PASSED_NULL_PARAMETER;
|
||||
goto err;
|
||||
}
|
||||
|
||||
ctx = BN_CTX_new();
|
||||
if (ctx == NULL) {
|
||||
reason = ERR_R_MALLOC_FAILURE;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (EC_GROUP_get_asn1_flag(x)) {
|
||||
/* the curve parameter are given by an asn1 OID */
|
||||
int nid;
|
||||
const char *nname;
|
||||
|
||||
if (!BIO_indent(bp, off, 128))
|
||||
goto err;
|
||||
|
||||
nid = EC_GROUP_get_curve_name(x);
|
||||
if (nid == 0)
|
||||
goto err;
|
||||
if (BIO_printf(bp, "ASN1 OID: %s", OBJ_nid2sn(nid)) <= 0)
|
||||
goto err;
|
||||
if (BIO_printf(bp, "\n") <= 0)
|
||||
goto err;
|
||||
nname = EC_curve_nid2nist(nid);
|
||||
if (nname) {
|
||||
if (!BIO_indent(bp, off, 128))
|
||||
goto err;
|
||||
if (BIO_printf(bp, "NIST CURVE: %s\n", nname) <= 0)
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
/* explicit parameters */
|
||||
int is_char_two = 0;
|
||||
point_conversion_form_t form;
|
||||
int tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(x));
|
||||
|
||||
if (tmp_nid == NID_X9_62_characteristic_two_field)
|
||||
is_char_two = 1;
|
||||
|
||||
if ((p = BN_new()) == NULL || (a = BN_new()) == NULL ||
|
||||
(b = BN_new()) == NULL) {
|
||||
reason = ERR_R_MALLOC_FAILURE;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!EC_GROUP_get_curve(x, p, a, b, ctx)) {
|
||||
reason = ERR_R_EC_LIB;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((point = EC_GROUP_get0_generator(x)) == NULL) {
|
||||
reason = ERR_R_EC_LIB;
|
||||
goto err;
|
||||
}
|
||||
order = EC_GROUP_get0_order(x);
|
||||
cofactor = EC_GROUP_get0_cofactor(x);
|
||||
if (order == NULL) {
|
||||
reason = ERR_R_EC_LIB;
|
||||
goto err;
|
||||
}
|
||||
|
||||
form = EC_GROUP_get_point_conversion_form(x);
|
||||
|
||||
if ((gen = EC_POINT_point2bn(x, point, form, NULL, ctx)) == NULL) {
|
||||
reason = ERR_R_EC_LIB;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((seed = EC_GROUP_get0_seed(x)) != NULL)
|
||||
seed_len = EC_GROUP_get_seed_len(x);
|
||||
|
||||
if (!BIO_indent(bp, off, 128))
|
||||
goto err;
|
||||
|
||||
/* print the 'short name' of the field type */
|
||||
if (BIO_printf(bp, "Field Type: %s\n", OBJ_nid2sn(tmp_nid))
|
||||
<= 0)
|
||||
goto err;
|
||||
|
||||
if (is_char_two) {
|
||||
/* print the 'short name' of the base type OID */
|
||||
int basis_type = EC_GROUP_get_basis_type(x);
|
||||
if (basis_type == 0)
|
||||
goto err;
|
||||
|
||||
if (!BIO_indent(bp, off, 128))
|
||||
goto err;
|
||||
|
||||
if (BIO_printf(bp, "Basis Type: %s\n",
|
||||
OBJ_nid2sn(basis_type)) <= 0)
|
||||
goto err;
|
||||
|
||||
/* print the polynomial */
|
||||
if ((p != NULL) && !ASN1_bn_print(bp, "Polynomial:", p, NULL,
|
||||
off))
|
||||
goto err;
|
||||
} else {
|
||||
if ((p != NULL) && !ASN1_bn_print(bp, "Prime:", p, NULL, off))
|
||||
goto err;
|
||||
}
|
||||
if ((a != NULL) && !ASN1_bn_print(bp, "A: ", a, NULL, off))
|
||||
goto err;
|
||||
if ((b != NULL) && !ASN1_bn_print(bp, "B: ", b, NULL, off))
|
||||
goto err;
|
||||
if (form == POINT_CONVERSION_COMPRESSED) {
|
||||
if ((gen != NULL) && !ASN1_bn_print(bp, gen_compressed, gen,
|
||||
NULL, off))
|
||||
goto err;
|
||||
} else if (form == POINT_CONVERSION_UNCOMPRESSED) {
|
||||
if ((gen != NULL) && !ASN1_bn_print(bp, gen_uncompressed, gen,
|
||||
NULL, off))
|
||||
goto err;
|
||||
} else { /* form == POINT_CONVERSION_HYBRID */
|
||||
|
||||
if ((gen != NULL) && !ASN1_bn_print(bp, gen_hybrid, gen,
|
||||
NULL, off))
|
||||
goto err;
|
||||
}
|
||||
if ((order != NULL) && !ASN1_bn_print(bp, "Order: ", order,
|
||||
NULL, off))
|
||||
goto err;
|
||||
if ((cofactor != NULL) && !ASN1_bn_print(bp, "Cofactor: ", cofactor,
|
||||
NULL, off))
|
||||
goto err;
|
||||
if (seed && !print_bin(bp, "Seed:", seed, seed_len, off))
|
||||
goto err;
|
||||
}
|
||||
ret = 1;
|
||||
err:
|
||||
if (!ret)
|
||||
ECerr(EC_F_ECPKPARAMETERS_PRINT, reason);
|
||||
BN_free(p);
|
||||
BN_free(a);
|
||||
BN_free(b);
|
||||
BN_free(gen);
|
||||
BN_CTX_free(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int print_bin(BIO *fp, const char *name, const unsigned char *buf,
|
||||
size_t len, int off)
|
||||
{
|
||||
size_t i;
|
||||
char str[128 + 1 + 4];
|
||||
|
||||
if (buf == NULL)
|
||||
return 1;
|
||||
if (off > 0) {
|
||||
if (off > 128)
|
||||
off = 128;
|
||||
memset(str, ' ', off);
|
||||
if (BIO_write(fp, str, off) <= 0)
|
||||
return 0;
|
||||
} else {
|
||||
off = 0;
|
||||
}
|
||||
|
||||
if (BIO_printf(fp, "%s", name) <= 0)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if ((i % 15) == 0) {
|
||||
str[0] = '\n';
|
||||
memset(&(str[1]), ' ', off + 4);
|
||||
if (BIO_write(fp, str, off + 1 + 4) <= 0)
|
||||
return 0;
|
||||
}
|
||||
if (BIO_printf(fp, "%02x%s", buf[i], ((i + 1) == len) ? "" : ":") <=
|
||||
0)
|
||||
return 0;
|
||||
}
|
||||
if (BIO_write(fp, "\n", 1) <= 0)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
291
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ecp_mont.c
vendored
Normal file
291
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ecp_mont.c
vendored
Normal file
|
@ -0,0 +1,291 @@
|
|||
/*
|
||||
* Copyright 2001-2019 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "ec_lcl.h"
|
||||
|
||||
const EC_METHOD *EC_GFp_mont_method(void)
|
||||
{
|
||||
static const EC_METHOD ret = {
|
||||
EC_FLAGS_DEFAULT_OCT,
|
||||
NID_X9_62_prime_field,
|
||||
ec_GFp_mont_group_init,
|
||||
ec_GFp_mont_group_finish,
|
||||
ec_GFp_mont_group_clear_finish,
|
||||
ec_GFp_mont_group_copy,
|
||||
ec_GFp_mont_group_set_curve,
|
||||
ec_GFp_simple_group_get_curve,
|
||||
ec_GFp_simple_group_get_degree,
|
||||
ec_group_simple_order_bits,
|
||||
ec_GFp_simple_group_check_discriminant,
|
||||
ec_GFp_simple_point_init,
|
||||
ec_GFp_simple_point_finish,
|
||||
ec_GFp_simple_point_clear_finish,
|
||||
ec_GFp_simple_point_copy,
|
||||
ec_GFp_simple_point_set_to_infinity,
|
||||
ec_GFp_simple_set_Jprojective_coordinates_GFp,
|
||||
ec_GFp_simple_get_Jprojective_coordinates_GFp,
|
||||
ec_GFp_simple_point_set_affine_coordinates,
|
||||
ec_GFp_simple_point_get_affine_coordinates,
|
||||
0, 0, 0,
|
||||
ec_GFp_simple_add,
|
||||
ec_GFp_simple_dbl,
|
||||
ec_GFp_simple_invert,
|
||||
ec_GFp_simple_is_at_infinity,
|
||||
ec_GFp_simple_is_on_curve,
|
||||
ec_GFp_simple_cmp,
|
||||
ec_GFp_simple_make_affine,
|
||||
ec_GFp_simple_points_make_affine,
|
||||
0 /* mul */ ,
|
||||
0 /* precompute_mult */ ,
|
||||
0 /* have_precompute_mult */ ,
|
||||
ec_GFp_mont_field_mul,
|
||||
ec_GFp_mont_field_sqr,
|
||||
0 /* field_div */ ,
|
||||
ec_GFp_mont_field_inv,
|
||||
ec_GFp_mont_field_encode,
|
||||
ec_GFp_mont_field_decode,
|
||||
ec_GFp_mont_field_set_to_one,
|
||||
ec_key_simple_priv2oct,
|
||||
ec_key_simple_oct2priv,
|
||||
0, /* set private */
|
||||
ec_key_simple_generate_key,
|
||||
ec_key_simple_check_key,
|
||||
ec_key_simple_generate_public_key,
|
||||
0, /* keycopy */
|
||||
0, /* keyfinish */
|
||||
ecdh_simple_compute_key,
|
||||
0, /* field_inverse_mod_ord */
|
||||
ec_GFp_simple_blind_coordinates,
|
||||
ec_GFp_simple_ladder_pre,
|
||||
ec_GFp_simple_ladder_step,
|
||||
ec_GFp_simple_ladder_post
|
||||
};
|
||||
|
||||
return &ret;
|
||||
}
|
||||
|
||||
int ec_GFp_mont_group_init(EC_GROUP *group)
|
||||
{
|
||||
int ok;
|
||||
|
||||
ok = ec_GFp_simple_group_init(group);
|
||||
group->field_data1 = NULL;
|
||||
group->field_data2 = NULL;
|
||||
return ok;
|
||||
}
|
||||
|
||||
void ec_GFp_mont_group_finish(EC_GROUP *group)
|
||||
{
|
||||
BN_MONT_CTX_free(group->field_data1);
|
||||
group->field_data1 = NULL;
|
||||
BN_free(group->field_data2);
|
||||
group->field_data2 = NULL;
|
||||
ec_GFp_simple_group_finish(group);
|
||||
}
|
||||
|
||||
void ec_GFp_mont_group_clear_finish(EC_GROUP *group)
|
||||
{
|
||||
BN_MONT_CTX_free(group->field_data1);
|
||||
group->field_data1 = NULL;
|
||||
BN_clear_free(group->field_data2);
|
||||
group->field_data2 = NULL;
|
||||
ec_GFp_simple_group_clear_finish(group);
|
||||
}
|
||||
|
||||
int ec_GFp_mont_group_copy(EC_GROUP *dest, const EC_GROUP *src)
|
||||
{
|
||||
BN_MONT_CTX_free(dest->field_data1);
|
||||
dest->field_data1 = NULL;
|
||||
BN_clear_free(dest->field_data2);
|
||||
dest->field_data2 = NULL;
|
||||
|
||||
if (!ec_GFp_simple_group_copy(dest, src))
|
||||
return 0;
|
||||
|
||||
if (src->field_data1 != NULL) {
|
||||
dest->field_data1 = BN_MONT_CTX_new();
|
||||
if (dest->field_data1 == NULL)
|
||||
return 0;
|
||||
if (!BN_MONT_CTX_copy(dest->field_data1, src->field_data1))
|
||||
goto err;
|
||||
}
|
||||
if (src->field_data2 != NULL) {
|
||||
dest->field_data2 = BN_dup(src->field_data2);
|
||||
if (dest->field_data2 == NULL)
|
||||
goto err;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
err:
|
||||
BN_MONT_CTX_free(dest->field_data1);
|
||||
dest->field_data1 = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p,
|
||||
const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
|
||||
{
|
||||
BN_CTX *new_ctx = NULL;
|
||||
BN_MONT_CTX *mont = NULL;
|
||||
BIGNUM *one = NULL;
|
||||
int ret = 0;
|
||||
|
||||
BN_MONT_CTX_free(group->field_data1);
|
||||
group->field_data1 = NULL;
|
||||
BN_free(group->field_data2);
|
||||
group->field_data2 = NULL;
|
||||
|
||||
if (ctx == NULL) {
|
||||
ctx = new_ctx = BN_CTX_new();
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
}
|
||||
|
||||
mont = BN_MONT_CTX_new();
|
||||
if (mont == NULL)
|
||||
goto err;
|
||||
if (!BN_MONT_CTX_set(mont, p, ctx)) {
|
||||
ECerr(EC_F_EC_GFP_MONT_GROUP_SET_CURVE, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
one = BN_new();
|
||||
if (one == NULL)
|
||||
goto err;
|
||||
if (!BN_to_montgomery(one, BN_value_one(), mont, ctx))
|
||||
goto err;
|
||||
|
||||
group->field_data1 = mont;
|
||||
mont = NULL;
|
||||
group->field_data2 = one;
|
||||
one = NULL;
|
||||
|
||||
ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
|
||||
|
||||
if (!ret) {
|
||||
BN_MONT_CTX_free(group->field_data1);
|
||||
group->field_data1 = NULL;
|
||||
BN_free(group->field_data2);
|
||||
group->field_data2 = NULL;
|
||||
}
|
||||
|
||||
err:
|
||||
BN_free(one);
|
||||
BN_CTX_free(new_ctx);
|
||||
BN_MONT_CTX_free(mont);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ec_GFp_mont_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
|
||||
const BIGNUM *b, BN_CTX *ctx)
|
||||
{
|
||||
if (group->field_data1 == NULL) {
|
||||
ECerr(EC_F_EC_GFP_MONT_FIELD_MUL, EC_R_NOT_INITIALIZED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return BN_mod_mul_montgomery(r, a, b, group->field_data1, ctx);
|
||||
}
|
||||
|
||||
int ec_GFp_mont_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
if (group->field_data1 == NULL) {
|
||||
ECerr(EC_F_EC_GFP_MONT_FIELD_SQR, EC_R_NOT_INITIALIZED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return BN_mod_mul_montgomery(r, a, a, group->field_data1, ctx);
|
||||
}
|
||||
|
||||
/*-
|
||||
* Computes the multiplicative inverse of a in GF(p), storing the result in r.
|
||||
* If a is zero (or equivalent), you'll get a EC_R_CANNOT_INVERT error.
|
||||
* We have a Mont structure, so SCA hardening is FLT inversion.
|
||||
*/
|
||||
int ec_GFp_mont_field_inv(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
BIGNUM *e = NULL;
|
||||
BN_CTX *new_ctx = NULL;
|
||||
int ret = 0;
|
||||
|
||||
if (group->field_data1 == NULL)
|
||||
return 0;
|
||||
|
||||
if (ctx == NULL && (ctx = new_ctx = BN_CTX_secure_new()) == NULL)
|
||||
return 0;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
if ((e = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
/* Inverse in constant time with Fermats Little Theorem */
|
||||
if (!BN_set_word(e, 2))
|
||||
goto err;
|
||||
if (!BN_sub(e, group->field, e))
|
||||
goto err;
|
||||
/*-
|
||||
* Exponent e is public.
|
||||
* No need for scatter-gather or BN_FLG_CONSTTIME.
|
||||
*/
|
||||
if (!BN_mod_exp_mont(r, a, e, group->field, ctx, group->field_data1))
|
||||
goto err;
|
||||
|
||||
/* throw an error on zero */
|
||||
if (BN_is_zero(r)) {
|
||||
ECerr(EC_F_EC_GFP_MONT_FIELD_INV, EC_R_CANNOT_INVERT);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ec_GFp_mont_field_encode(const EC_GROUP *group, BIGNUM *r,
|
||||
const BIGNUM *a, BN_CTX *ctx)
|
||||
{
|
||||
if (group->field_data1 == NULL) {
|
||||
ECerr(EC_F_EC_GFP_MONT_FIELD_ENCODE, EC_R_NOT_INITIALIZED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return BN_to_montgomery(r, a, (BN_MONT_CTX *)group->field_data1, ctx);
|
||||
}
|
||||
|
||||
int ec_GFp_mont_field_decode(const EC_GROUP *group, BIGNUM *r,
|
||||
const BIGNUM *a, BN_CTX *ctx)
|
||||
{
|
||||
if (group->field_data1 == NULL) {
|
||||
ECerr(EC_F_EC_GFP_MONT_FIELD_DECODE, EC_R_NOT_INITIALIZED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return BN_from_montgomery(r, a, group->field_data1, ctx);
|
||||
}
|
||||
|
||||
int ec_GFp_mont_field_set_to_one(const EC_GROUP *group, BIGNUM *r,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
if (group->field_data2 == NULL) {
|
||||
ECerr(EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE, EC_R_NOT_INITIALIZED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!BN_copy(r, group->field_data2))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
168
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ecp_nist.c
vendored
Normal file
168
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ecp_nist.c
vendored
Normal file
|
@ -0,0 +1,168 @@
|
|||
/*
|
||||
* Copyright 2001-2019 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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/obj_mac.h>
|
||||
#include "ec_lcl.h"
|
||||
|
||||
const EC_METHOD *EC_GFp_nist_method(void)
|
||||
{
|
||||
static const EC_METHOD ret = {
|
||||
EC_FLAGS_DEFAULT_OCT,
|
||||
NID_X9_62_prime_field,
|
||||
ec_GFp_simple_group_init,
|
||||
ec_GFp_simple_group_finish,
|
||||
ec_GFp_simple_group_clear_finish,
|
||||
ec_GFp_nist_group_copy,
|
||||
ec_GFp_nist_group_set_curve,
|
||||
ec_GFp_simple_group_get_curve,
|
||||
ec_GFp_simple_group_get_degree,
|
||||
ec_group_simple_order_bits,
|
||||
ec_GFp_simple_group_check_discriminant,
|
||||
ec_GFp_simple_point_init,
|
||||
ec_GFp_simple_point_finish,
|
||||
ec_GFp_simple_point_clear_finish,
|
||||
ec_GFp_simple_point_copy,
|
||||
ec_GFp_simple_point_set_to_infinity,
|
||||
ec_GFp_simple_set_Jprojective_coordinates_GFp,
|
||||
ec_GFp_simple_get_Jprojective_coordinates_GFp,
|
||||
ec_GFp_simple_point_set_affine_coordinates,
|
||||
ec_GFp_simple_point_get_affine_coordinates,
|
||||
0, 0, 0,
|
||||
ec_GFp_simple_add,
|
||||
ec_GFp_simple_dbl,
|
||||
ec_GFp_simple_invert,
|
||||
ec_GFp_simple_is_at_infinity,
|
||||
ec_GFp_simple_is_on_curve,
|
||||
ec_GFp_simple_cmp,
|
||||
ec_GFp_simple_make_affine,
|
||||
ec_GFp_simple_points_make_affine,
|
||||
0 /* mul */ ,
|
||||
0 /* precompute_mult */ ,
|
||||
0 /* have_precompute_mult */ ,
|
||||
ec_GFp_nist_field_mul,
|
||||
ec_GFp_nist_field_sqr,
|
||||
0 /* field_div */ ,
|
||||
ec_GFp_simple_field_inv,
|
||||
0 /* field_encode */ ,
|
||||
0 /* field_decode */ ,
|
||||
0, /* field_set_to_one */
|
||||
ec_key_simple_priv2oct,
|
||||
ec_key_simple_oct2priv,
|
||||
0, /* set private */
|
||||
ec_key_simple_generate_key,
|
||||
ec_key_simple_check_key,
|
||||
ec_key_simple_generate_public_key,
|
||||
0, /* keycopy */
|
||||
0, /* keyfinish */
|
||||
ecdh_simple_compute_key,
|
||||
0, /* field_inverse_mod_ord */
|
||||
ec_GFp_simple_blind_coordinates,
|
||||
ec_GFp_simple_ladder_pre,
|
||||
ec_GFp_simple_ladder_step,
|
||||
ec_GFp_simple_ladder_post
|
||||
};
|
||||
|
||||
return &ret;
|
||||
}
|
||||
|
||||
int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src)
|
||||
{
|
||||
dest->field_mod_func = src->field_mod_func;
|
||||
|
||||
return ec_GFp_simple_group_copy(dest, src);
|
||||
}
|
||||
|
||||
int ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p,
|
||||
const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
BN_CTX *new_ctx = NULL;
|
||||
|
||||
if (ctx == NULL)
|
||||
if ((ctx = new_ctx = BN_CTX_new()) == NULL)
|
||||
return 0;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
if (BN_ucmp(BN_get0_nist_prime_192(), p) == 0)
|
||||
group->field_mod_func = BN_nist_mod_192;
|
||||
else if (BN_ucmp(BN_get0_nist_prime_224(), p) == 0)
|
||||
group->field_mod_func = BN_nist_mod_224;
|
||||
else if (BN_ucmp(BN_get0_nist_prime_256(), p) == 0)
|
||||
group->field_mod_func = BN_nist_mod_256;
|
||||
else if (BN_ucmp(BN_get0_nist_prime_384(), p) == 0)
|
||||
group->field_mod_func = BN_nist_mod_384;
|
||||
else if (BN_ucmp(BN_get0_nist_prime_521(), p) == 0)
|
||||
group->field_mod_func = BN_nist_mod_521;
|
||||
else {
|
||||
ECerr(EC_F_EC_GFP_NIST_GROUP_SET_CURVE, EC_R_NOT_A_NIST_PRIME);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ec_GFp_nist_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
|
||||
const BIGNUM *b, BN_CTX *ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
BN_CTX *ctx_new = NULL;
|
||||
|
||||
if (!group || !r || !a || !b) {
|
||||
ECerr(EC_F_EC_GFP_NIST_FIELD_MUL, ERR_R_PASSED_NULL_PARAMETER);
|
||||
goto err;
|
||||
}
|
||||
if (!ctx)
|
||||
if ((ctx_new = ctx = BN_CTX_new()) == NULL)
|
||||
goto err;
|
||||
|
||||
if (!BN_mul(r, a, b, ctx))
|
||||
goto err;
|
||||
if (!group->field_mod_func(r, r, group->field, ctx))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
err:
|
||||
BN_CTX_free(ctx_new);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ec_GFp_nist_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
BN_CTX *ctx_new = NULL;
|
||||
|
||||
if (!group || !r || !a) {
|
||||
ECerr(EC_F_EC_GFP_NIST_FIELD_SQR, EC_R_PASSED_NULL_PARAMETER);
|
||||
goto err;
|
||||
}
|
||||
if (!ctx)
|
||||
if ((ctx_new = ctx = BN_CTX_new()) == NULL)
|
||||
goto err;
|
||||
|
||||
if (!BN_sqr(r, a, ctx))
|
||||
goto err;
|
||||
if (!group->field_mod_func(r, r, group->field, ctx))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
err:
|
||||
BN_CTX_free(ctx_new);
|
||||
return ret;
|
||||
}
|
1716
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ecp_nistp224.c
vendored
Normal file
1716
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ecp_nistp224.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
2355
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ecp_nistp256.c
vendored
Normal file
2355
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ecp_nistp256.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
2159
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ecp_nistp521.c
vendored
Normal file
2159
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ecp_nistp521.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
223
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ecp_nistputil.c
vendored
Normal file
223
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ecp_nistputil.c
vendored
Normal file
|
@ -0,0 +1,223 @@
|
|||
/*
|
||||
* Copyright 2011-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
|
||||
*/
|
||||
|
||||
/* Copyright 2011 Google Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
#ifdef OPENSSL_NO_EC_NISTP_64_GCC_128
|
||||
NON_EMPTY_TRANSLATION_UNIT
|
||||
#else
|
||||
|
||||
/*
|
||||
* Common utility functions for ecp_nistp224.c, ecp_nistp256.c, ecp_nistp521.c.
|
||||
*/
|
||||
|
||||
# include <stddef.h>
|
||||
# include "ec_lcl.h"
|
||||
|
||||
/*
|
||||
* Convert an array of points into affine coordinates. (If the point at
|
||||
* infinity is found (Z = 0), it remains unchanged.) This function is
|
||||
* essentially an equivalent to EC_POINTs_make_affine(), but works with the
|
||||
* internal representation of points as used by ecp_nistp###.c rather than
|
||||
* with (BIGNUM-based) EC_POINT data structures. point_array is the
|
||||
* input/output buffer ('num' points in projective form, i.e. three
|
||||
* coordinates each), based on an internal representation of field elements
|
||||
* of size 'felem_size'. tmp_felems needs to point to a temporary array of
|
||||
* 'num'+1 field elements for storage of intermediate values.
|
||||
*/
|
||||
void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array,
|
||||
size_t felem_size,
|
||||
void *tmp_felems,
|
||||
void (*felem_one) (void *out),
|
||||
int (*felem_is_zero) (const void
|
||||
*in),
|
||||
void (*felem_assign) (void *out,
|
||||
const void
|
||||
*in),
|
||||
void (*felem_square) (void *out,
|
||||
const void
|
||||
*in),
|
||||
void (*felem_mul) (void *out,
|
||||
const void
|
||||
*in1,
|
||||
const void
|
||||
*in2),
|
||||
void (*felem_inv) (void *out,
|
||||
const void
|
||||
*in),
|
||||
void (*felem_contract) (void
|
||||
*out,
|
||||
const
|
||||
void
|
||||
*in))
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
# define tmp_felem(I) (&((char *)tmp_felems)[(I) * felem_size])
|
||||
# define X(I) (&((char *)point_array)[3*(I) * felem_size])
|
||||
# define Y(I) (&((char *)point_array)[(3*(I) + 1) * felem_size])
|
||||
# define Z(I) (&((char *)point_array)[(3*(I) + 2) * felem_size])
|
||||
|
||||
if (!felem_is_zero(Z(0)))
|
||||
felem_assign(tmp_felem(0), Z(0));
|
||||
else
|
||||
felem_one(tmp_felem(0));
|
||||
for (i = 1; i < (int)num; i++) {
|
||||
if (!felem_is_zero(Z(i)))
|
||||
felem_mul(tmp_felem(i), tmp_felem(i - 1), Z(i));
|
||||
else
|
||||
felem_assign(tmp_felem(i), tmp_felem(i - 1));
|
||||
}
|
||||
/*
|
||||
* Now each tmp_felem(i) is the product of Z(0) .. Z(i), skipping any
|
||||
* zero-valued factors: if Z(i) = 0, we essentially pretend that Z(i) = 1
|
||||
*/
|
||||
|
||||
felem_inv(tmp_felem(num - 1), tmp_felem(num - 1));
|
||||
for (i = num - 1; i >= 0; i--) {
|
||||
if (i > 0)
|
||||
/*
|
||||
* tmp_felem(i-1) is the product of Z(0) .. Z(i-1), tmp_felem(i)
|
||||
* is the inverse of the product of Z(0) .. Z(i)
|
||||
*/
|
||||
/* 1/Z(i) */
|
||||
felem_mul(tmp_felem(num), tmp_felem(i - 1), tmp_felem(i));
|
||||
else
|
||||
felem_assign(tmp_felem(num), tmp_felem(0)); /* 1/Z(0) */
|
||||
|
||||
if (!felem_is_zero(Z(i))) {
|
||||
if (i > 0)
|
||||
/*
|
||||
* For next iteration, replace tmp_felem(i-1) by its inverse
|
||||
*/
|
||||
felem_mul(tmp_felem(i - 1), tmp_felem(i), Z(i));
|
||||
|
||||
/*
|
||||
* Convert point (X, Y, Z) into affine form (X/(Z^2), Y/(Z^3), 1)
|
||||
*/
|
||||
felem_square(Z(i), tmp_felem(num)); /* 1/(Z^2) */
|
||||
felem_mul(X(i), X(i), Z(i)); /* X/(Z^2) */
|
||||
felem_mul(Z(i), Z(i), tmp_felem(num)); /* 1/(Z^3) */
|
||||
felem_mul(Y(i), Y(i), Z(i)); /* Y/(Z^3) */
|
||||
felem_contract(X(i), X(i));
|
||||
felem_contract(Y(i), Y(i));
|
||||
felem_one(Z(i));
|
||||
} else {
|
||||
if (i > 0)
|
||||
/*
|
||||
* For next iteration, replace tmp_felem(i-1) by its inverse
|
||||
*/
|
||||
felem_assign(tmp_felem(i - 1), tmp_felem(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-
|
||||
* This function looks at 5+1 scalar bits (5 current, 1 adjacent less
|
||||
* significant bit), and recodes them into a signed digit for use in fast point
|
||||
* multiplication: the use of signed rather than unsigned digits means that
|
||||
* fewer points need to be precomputed, given that point inversion is easy
|
||||
* (a precomputed point dP makes -dP available as well).
|
||||
*
|
||||
* BACKGROUND:
|
||||
*
|
||||
* Signed digits for multiplication were introduced by Booth ("A signed binary
|
||||
* multiplication technique", Quart. Journ. Mech. and Applied Math., vol. IV,
|
||||
* pt. 2 (1951), pp. 236-240), in that case for multiplication of integers.
|
||||
* Booth's original encoding did not generally improve the density of nonzero
|
||||
* digits over the binary representation, and was merely meant to simplify the
|
||||
* handling of signed factors given in two's complement; but it has since been
|
||||
* shown to be the basis of various signed-digit representations that do have
|
||||
* further advantages, including the wNAF, using the following general approach:
|
||||
*
|
||||
* (1) Given a binary representation
|
||||
*
|
||||
* b_k ... b_2 b_1 b_0,
|
||||
*
|
||||
* of a nonnegative integer (b_k in {0, 1}), rewrite it in digits 0, 1, -1
|
||||
* by using bit-wise subtraction as follows:
|
||||
*
|
||||
* b_k b_(k-1) ... b_2 b_1 b_0
|
||||
* - b_k ... b_3 b_2 b_1 b_0
|
||||
* -------------------------------------
|
||||
* s_k b_(k-1) ... s_3 s_2 s_1 s_0
|
||||
*
|
||||
* A left-shift followed by subtraction of the original value yields a new
|
||||
* representation of the same value, using signed bits s_i = b_(i+1) - b_i.
|
||||
* This representation from Booth's paper has since appeared in the
|
||||
* literature under a variety of different names including "reversed binary
|
||||
* form", "alternating greedy expansion", "mutual opposite form", and
|
||||
* "sign-alternating {+-1}-representation".
|
||||
*
|
||||
* An interesting property is that among the nonzero bits, values 1 and -1
|
||||
* strictly alternate.
|
||||
*
|
||||
* (2) Various window schemes can be applied to the Booth representation of
|
||||
* integers: for example, right-to-left sliding windows yield the wNAF
|
||||
* (a signed-digit encoding independently discovered by various researchers
|
||||
* in the 1990s), and left-to-right sliding windows yield a left-to-right
|
||||
* equivalent of the wNAF (independently discovered by various researchers
|
||||
* around 2004).
|
||||
*
|
||||
* To prevent leaking information through side channels in point multiplication,
|
||||
* we need to recode the given integer into a regular pattern: sliding windows
|
||||
* as in wNAFs won't do, we need their fixed-window equivalent -- which is a few
|
||||
* decades older: we'll be using the so-called "modified Booth encoding" due to
|
||||
* MacSorley ("High-speed arithmetic in binary computers", Proc. IRE, vol. 49
|
||||
* (1961), pp. 67-91), in a radix-2^5 setting. That is, we always combine five
|
||||
* signed bits into a signed digit:
|
||||
*
|
||||
* s_(4j + 4) s_(4j + 3) s_(4j + 2) s_(4j + 1) s_(4j)
|
||||
*
|
||||
* The sign-alternating property implies that the resulting digit values are
|
||||
* integers from -16 to 16.
|
||||
*
|
||||
* Of course, we don't actually need to compute the signed digits s_i as an
|
||||
* intermediate step (that's just a nice way to see how this scheme relates
|
||||
* to the wNAF): a direct computation obtains the recoded digit from the
|
||||
* six bits b_(4j + 4) ... b_(4j - 1).
|
||||
*
|
||||
* This function takes those five bits as an integer (0 .. 63), writing the
|
||||
* recoded digit to *sign (0 for positive, 1 for negative) and *digit (absolute
|
||||
* value, in the range 0 .. 8). Note that this integer essentially provides the
|
||||
* input bits "shifted to the left" by one position: for example, the input to
|
||||
* compute the least significant recoded digit, given that there's no bit b_-1,
|
||||
* has to be b_4 b_3 b_2 b_1 b_0 0.
|
||||
*
|
||||
*/
|
||||
void ec_GFp_nistp_recode_scalar_bits(unsigned char *sign,
|
||||
unsigned char *digit, unsigned char in)
|
||||
{
|
||||
unsigned char s, d;
|
||||
|
||||
s = ~((in >> 5) - 1); /* sets all bits to MSB(in), 'in' seen as
|
||||
* 6-bit value */
|
||||
d = (1 << 6) - in - 1;
|
||||
d = (d & s) | (in & ~s);
|
||||
d = (d >> 1) + (d & 1);
|
||||
|
||||
*sign = s & 1;
|
||||
*digit = d;
|
||||
}
|
||||
#endif
|
1701
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ecp_nistz256.c
vendored
Normal file
1701
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ecp_nistz256.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
9542
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ecp_nistz256_table.c
vendored
Normal file
9542
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ecp_nistz256_table.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
366
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ecp_oct.c
vendored
Normal file
366
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ecp_oct.c
vendored
Normal file
|
@ -0,0 +1,366 @@
|
|||
/*
|
||||
* Copyright 2011-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
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/symhacks.h>
|
||||
|
||||
#include "ec_lcl.h"
|
||||
|
||||
int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group,
|
||||
EC_POINT *point,
|
||||
const BIGNUM *x_, int y_bit,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
BN_CTX *new_ctx = NULL;
|
||||
BIGNUM *tmp1, *tmp2, *x, *y;
|
||||
int ret = 0;
|
||||
|
||||
/* clear error queue */
|
||||
ERR_clear_error();
|
||||
|
||||
if (ctx == NULL) {
|
||||
ctx = new_ctx = BN_CTX_new();
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
}
|
||||
|
||||
y_bit = (y_bit != 0);
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
tmp1 = BN_CTX_get(ctx);
|
||||
tmp2 = BN_CTX_get(ctx);
|
||||
x = BN_CTX_get(ctx);
|
||||
y = BN_CTX_get(ctx);
|
||||
if (y == NULL)
|
||||
goto err;
|
||||
|
||||
/*-
|
||||
* Recover y. We have a Weierstrass equation
|
||||
* y^2 = x^3 + a*x + b,
|
||||
* so y is one of the square roots of x^3 + a*x + b.
|
||||
*/
|
||||
|
||||
/* tmp1 := x^3 */
|
||||
if (!BN_nnmod(x, x_, group->field, ctx))
|
||||
goto err;
|
||||
if (group->meth->field_decode == 0) {
|
||||
/* field_{sqr,mul} work on standard representation */
|
||||
if (!group->meth->field_sqr(group, tmp2, x_, ctx))
|
||||
goto err;
|
||||
if (!group->meth->field_mul(group, tmp1, tmp2, x_, ctx))
|
||||
goto err;
|
||||
} else {
|
||||
if (!BN_mod_sqr(tmp2, x_, group->field, ctx))
|
||||
goto err;
|
||||
if (!BN_mod_mul(tmp1, tmp2, x_, group->field, ctx))
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* tmp1 := tmp1 + a*x */
|
||||
if (group->a_is_minus3) {
|
||||
if (!BN_mod_lshift1_quick(tmp2, x, group->field))
|
||||
goto err;
|
||||
if (!BN_mod_add_quick(tmp2, tmp2, x, group->field))
|
||||
goto err;
|
||||
if (!BN_mod_sub_quick(tmp1, tmp1, tmp2, group->field))
|
||||
goto err;
|
||||
} else {
|
||||
if (group->meth->field_decode) {
|
||||
if (!group->meth->field_decode(group, tmp2, group->a, ctx))
|
||||
goto err;
|
||||
if (!BN_mod_mul(tmp2, tmp2, x, group->field, ctx))
|
||||
goto err;
|
||||
} else {
|
||||
/* field_mul works on standard representation */
|
||||
if (!group->meth->field_mul(group, tmp2, group->a, x, ctx))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!BN_mod_add_quick(tmp1, tmp1, tmp2, group->field))
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* tmp1 := tmp1 + b */
|
||||
if (group->meth->field_decode) {
|
||||
if (!group->meth->field_decode(group, tmp2, group->b, ctx))
|
||||
goto err;
|
||||
if (!BN_mod_add_quick(tmp1, tmp1, tmp2, group->field))
|
||||
goto err;
|
||||
} else {
|
||||
if (!BN_mod_add_quick(tmp1, tmp1, group->b, group->field))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!BN_mod_sqrt(y, tmp1, group->field, ctx)) {
|
||||
unsigned long err = ERR_peek_last_error();
|
||||
|
||||
if (ERR_GET_LIB(err) == ERR_LIB_BN
|
||||
&& ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE) {
|
||||
ERR_clear_error();
|
||||
ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES,
|
||||
EC_R_INVALID_COMPRESSED_POINT);
|
||||
} else
|
||||
ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES,
|
||||
ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (y_bit != BN_is_odd(y)) {
|
||||
if (BN_is_zero(y)) {
|
||||
int kron;
|
||||
|
||||
kron = BN_kronecker(x, group->field, ctx);
|
||||
if (kron == -2)
|
||||
goto err;
|
||||
|
||||
if (kron == 1)
|
||||
ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES,
|
||||
EC_R_INVALID_COMPRESSION_BIT);
|
||||
else
|
||||
/*
|
||||
* 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);
|
||||
goto err;
|
||||
}
|
||||
if (!BN_usub(y, group->field, y))
|
||||
goto err;
|
||||
}
|
||||
if (y_bit != BN_is_odd(y)) {
|
||||
ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES,
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!EC_POINT_set_affine_coordinates(group, point, x, y, ctx))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point,
|
||||
point_conversion_form_t form,
|
||||
unsigned char *buf, size_t len, BN_CTX *ctx)
|
||||
{
|
||||
size_t ret;
|
||||
BN_CTX *new_ctx = NULL;
|
||||
int used_ctx = 0;
|
||||
BIGNUM *x, *y;
|
||||
size_t field_len, i, skip;
|
||||
|
||||
if ((form != POINT_CONVERSION_COMPRESSED)
|
||||
&& (form != POINT_CONVERSION_UNCOMPRESSED)
|
||||
&& (form != POINT_CONVERSION_HYBRID)) {
|
||||
ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_INVALID_FORM);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (EC_POINT_is_at_infinity(group, point)) {
|
||||
/* encodes to a single 0 octet */
|
||||
if (buf != NULL) {
|
||||
if (len < 1) {
|
||||
ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
buf[0] = 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ret := required output buffer length */
|
||||
field_len = BN_num_bytes(group->field);
|
||||
ret =
|
||||
(form ==
|
||||
POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len;
|
||||
|
||||
/* if 'buf' is NULL, just return required length */
|
||||
if (buf != NULL) {
|
||||
if (len < ret) {
|
||||
ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (ctx == NULL) {
|
||||
ctx = new_ctx = BN_CTX_new();
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
}
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
used_ctx = 1;
|
||||
x = BN_CTX_get(ctx);
|
||||
y = BN_CTX_get(ctx);
|
||||
if (y == NULL)
|
||||
goto err;
|
||||
|
||||
if (!EC_POINT_get_affine_coordinates(group, point, x, y, ctx))
|
||||
goto err;
|
||||
|
||||
if ((form == POINT_CONVERSION_COMPRESSED
|
||||
|| form == POINT_CONVERSION_HYBRID) && BN_is_odd(y))
|
||||
buf[0] = form + 1;
|
||||
else
|
||||
buf[0] = form;
|
||||
|
||||
i = 1;
|
||||
|
||||
skip = field_len - BN_num_bytes(x);
|
||||
if (skip > field_len) {
|
||||
ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
while (skip > 0) {
|
||||
buf[i++] = 0;
|
||||
skip--;
|
||||
}
|
||||
skip = BN_bn2bin(x, buf + i);
|
||||
i += skip;
|
||||
if (i != 1 + field_len) {
|
||||
ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (form == POINT_CONVERSION_UNCOMPRESSED
|
||||
|| form == POINT_CONVERSION_HYBRID) {
|
||||
skip = field_len - BN_num_bytes(y);
|
||||
if (skip > field_len) {
|
||||
ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
while (skip > 0) {
|
||||
buf[i++] = 0;
|
||||
skip--;
|
||||
}
|
||||
skip = BN_bn2bin(y, buf + i);
|
||||
i += skip;
|
||||
}
|
||||
|
||||
if (i != ret) {
|
||||
ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (used_ctx)
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
|
||||
err:
|
||||
if (used_ctx)
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
|
||||
const unsigned char *buf, size_t len, BN_CTX *ctx)
|
||||
{
|
||||
point_conversion_form_t form;
|
||||
int y_bit;
|
||||
BN_CTX *new_ctx = NULL;
|
||||
BIGNUM *x, *y;
|
||||
size_t field_len, enc_len;
|
||||
int ret = 0;
|
||||
|
||||
if (len == 0) {
|
||||
ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
form = buf[0];
|
||||
y_bit = form & 1;
|
||||
form = form & ~1U;
|
||||
if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED)
|
||||
&& (form != POINT_CONVERSION_UNCOMPRESSED)
|
||||
&& (form != POINT_CONVERSION_HYBRID)) {
|
||||
ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
|
||||
return 0;
|
||||
}
|
||||
if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) {
|
||||
ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (form == 0) {
|
||||
if (len != 1) {
|
||||
ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return EC_POINT_set_to_infinity(group, point);
|
||||
}
|
||||
|
||||
field_len = BN_num_bytes(group->field);
|
||||
enc_len =
|
||||
(form ==
|
||||
POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len;
|
||||
|
||||
if (len != enc_len) {
|
||||
ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ctx == NULL) {
|
||||
ctx = new_ctx = BN_CTX_new();
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
}
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
x = BN_CTX_get(ctx);
|
||||
y = BN_CTX_get(ctx);
|
||||
if (y == NULL)
|
||||
goto err;
|
||||
|
||||
if (!BN_bin2bn(buf + 1, field_len, x))
|
||||
goto err;
|
||||
if (BN_ucmp(x, group->field) >= 0) {
|
||||
ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (form == POINT_CONVERSION_COMPRESSED) {
|
||||
if (!EC_POINT_set_compressed_coordinates(group, point, x, y_bit, ctx))
|
||||
goto err;
|
||||
} else {
|
||||
if (!BN_bin2bn(buf + 1 + field_len, field_len, y))
|
||||
goto err;
|
||||
if (BN_ucmp(y, group->field) >= 0) {
|
||||
ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
|
||||
goto err;
|
||||
}
|
||||
if (form == POINT_CONVERSION_HYBRID) {
|
||||
if (y_bit != BN_is_odd(y)) {
|
||||
ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* EC_POINT_set_affine_coordinates is responsible for checking that
|
||||
* the point is on the curve.
|
||||
*/
|
||||
if (!EC_POINT_set_affine_coordinates(group, point, x, y, ctx))
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
}
|
1689
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ecp_smpl.c
vendored
Normal file
1689
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ecp_smpl.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
841
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ecx_meth.c
vendored
Normal file
841
trunk/3rdparty/openssl-1.1-fit/crypto/ec/ecx_meth.c
vendored
Normal file
|
@ -0,0 +1,841 @@
|
|||
/*
|
||||
* Copyright 2006-2019 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
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/rand.h>
|
||||
#include "internal/asn1_int.h"
|
||||
#include "internal/evp_int.h"
|
||||
#include "ec_lcl.h"
|
||||
#include "curve448/curve448_lcl.h"
|
||||
|
||||
#define X25519_BITS 253
|
||||
#define X25519_SECURITY_BITS 128
|
||||
|
||||
#define ED25519_SIGSIZE 64
|
||||
|
||||
#define X448_BITS 448
|
||||
#define ED448_BITS 456
|
||||
#define X448_SECURITY_BITS 224
|
||||
|
||||
#define ED448_SIGSIZE 114
|
||||
|
||||
#define ISX448(id) ((id) == EVP_PKEY_X448)
|
||||
#define IS25519(id) ((id) == EVP_PKEY_X25519 || (id) == EVP_PKEY_ED25519)
|
||||
#define KEYLENID(id) (IS25519(id) ? X25519_KEYLEN \
|
||||
: ((id) == EVP_PKEY_X448 ? X448_KEYLEN \
|
||||
: ED448_KEYLEN))
|
||||
#define KEYLEN(p) KEYLENID((p)->ameth->pkey_id)
|
||||
|
||||
|
||||
typedef enum {
|
||||
KEY_OP_PUBLIC,
|
||||
KEY_OP_PRIVATE,
|
||||
KEY_OP_KEYGEN
|
||||
} ecx_key_op_t;
|
||||
|
||||
/* Setup EVP_PKEY using public, private or generation */
|
||||
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)
|
||||
{
|
||||
ECX_KEY *key = NULL;
|
||||
unsigned char *privkey, *pubkey;
|
||||
|
||||
if (op != KEY_OP_KEYGEN) {
|
||||
if (palg != NULL) {
|
||||
int ptype;
|
||||
|
||||
/* Algorithm parameters must be absent */
|
||||
X509_ALGOR_get0(NULL, &ptype, NULL, palg);
|
||||
if (ptype != V_ASN1_UNDEF) {
|
||||
ECerr(EC_F_ECX_KEY_OP, EC_R_INVALID_ENCODING);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (p == NULL || plen != KEYLENID(id)) {
|
||||
ECerr(EC_F_ECX_KEY_OP, EC_R_INVALID_ENCODING);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
key = OPENSSL_zalloc(sizeof(*key));
|
||||
if (key == NULL) {
|
||||
ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
pubkey = key->pubkey;
|
||||
|
||||
if (op == KEY_OP_PUBLIC) {
|
||||
memcpy(pubkey, p, plen);
|
||||
} else {
|
||||
privkey = key->privkey = OPENSSL_secure_malloc(KEYLENID(id));
|
||||
if (privkey == NULL) {
|
||||
ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
if (op == KEY_OP_KEYGEN) {
|
||||
if (RAND_priv_bytes(privkey, KEYLENID(id)) <= 0) {
|
||||
OPENSSL_secure_free(privkey);
|
||||
key->privkey = NULL;
|
||||
goto err;
|
||||
}
|
||||
if (id == EVP_PKEY_X25519) {
|
||||
privkey[0] &= 248;
|
||||
privkey[X25519_KEYLEN - 1] &= 127;
|
||||
privkey[X25519_KEYLEN - 1] |= 64;
|
||||
} else if (id == EVP_PKEY_X448) {
|
||||
privkey[0] &= 252;
|
||||
privkey[X448_KEYLEN - 1] |= 128;
|
||||
}
|
||||
} else {
|
||||
memcpy(privkey, p, KEYLENID(id));
|
||||
}
|
||||
switch (id) {
|
||||
case EVP_PKEY_X25519:
|
||||
X25519_public_from_private(pubkey, privkey);
|
||||
break;
|
||||
case EVP_PKEY_ED25519:
|
||||
ED25519_public_from_private(pubkey, privkey);
|
||||
break;
|
||||
case EVP_PKEY_X448:
|
||||
X448_public_from_private(pubkey, privkey);
|
||||
break;
|
||||
case EVP_PKEY_ED448:
|
||||
ED448_public_from_private(pubkey, privkey);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
EVP_PKEY_assign(pkey, id, key);
|
||||
return 1;
|
||||
err:
|
||||
OPENSSL_free(key);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ecx_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
|
||||
{
|
||||
const ECX_KEY *ecxkey = pkey->pkey.ecx;
|
||||
unsigned char *penc;
|
||||
|
||||
if (ecxkey == NULL) {
|
||||
ECerr(EC_F_ECX_PUB_ENCODE, EC_R_INVALID_KEY);
|
||||
return 0;
|
||||
}
|
||||
|
||||
penc = OPENSSL_memdup(ecxkey->pubkey, KEYLEN(pkey));
|
||||
if (penc == NULL) {
|
||||
ECerr(EC_F_ECX_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!X509_PUBKEY_set0_param(pk, OBJ_nid2obj(pkey->ameth->pkey_id),
|
||||
V_ASN1_UNDEF, NULL, penc, KEYLEN(pkey))) {
|
||||
OPENSSL_free(penc);
|
||||
ECerr(EC_F_ECX_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ecx_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
|
||||
{
|
||||
const unsigned char *p;
|
||||
int pklen;
|
||||
X509_ALGOR *palg;
|
||||
|
||||
if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
|
||||
return 0;
|
||||
return ecx_key_op(pkey, pkey->ameth->pkey_id, palg, p, pklen,
|
||||
KEY_OP_PUBLIC);
|
||||
}
|
||||
|
||||
static int ecx_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
|
||||
{
|
||||
const ECX_KEY *akey = a->pkey.ecx;
|
||||
const ECX_KEY *bkey = b->pkey.ecx;
|
||||
|
||||
if (akey == NULL || bkey == NULL)
|
||||
return -2;
|
||||
|
||||
return CRYPTO_memcmp(akey->pubkey, bkey->pubkey, KEYLEN(a)) == 0;
|
||||
}
|
||||
|
||||
static int ecx_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
|
||||
{
|
||||
const unsigned char *p;
|
||||
int plen;
|
||||
ASN1_OCTET_STRING *oct = NULL;
|
||||
const X509_ALGOR *palg;
|
||||
int rv;
|
||||
|
||||
if (!PKCS8_pkey_get0(NULL, &p, &plen, &palg, p8))
|
||||
return 0;
|
||||
|
||||
oct = d2i_ASN1_OCTET_STRING(NULL, &p, plen);
|
||||
if (oct == NULL) {
|
||||
p = NULL;
|
||||
plen = 0;
|
||||
} else {
|
||||
p = ASN1_STRING_get0_data(oct);
|
||||
plen = ASN1_STRING_length(oct);
|
||||
}
|
||||
|
||||
rv = ecx_key_op(pkey, pkey->ameth->pkey_id, palg, p, plen, KEY_OP_PRIVATE);
|
||||
ASN1_OCTET_STRING_free(oct);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int ecx_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
|
||||
{
|
||||
const ECX_KEY *ecxkey = pkey->pkey.ecx;
|
||||
ASN1_OCTET_STRING oct;
|
||||
unsigned char *penc = NULL;
|
||||
int penclen;
|
||||
|
||||
if (ecxkey == NULL || ecxkey->privkey == NULL) {
|
||||
ECerr(EC_F_ECX_PRIV_ENCODE, EC_R_INVALID_PRIVATE_KEY);
|
||||
return 0;
|
||||
}
|
||||
|
||||
oct.data = ecxkey->privkey;
|
||||
oct.length = KEYLEN(pkey);
|
||||
oct.flags = 0;
|
||||
|
||||
penclen = i2d_ASN1_OCTET_STRING(&oct, &penc);
|
||||
if (penclen < 0) {
|
||||
ECerr(EC_F_ECX_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
|
||||
return 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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ecx_size(const EVP_PKEY *pkey)
|
||||
{
|
||||
return KEYLEN(pkey);
|
||||
}
|
||||
|
||||
static int ecx_bits(const EVP_PKEY *pkey)
|
||||
{
|
||||
if (IS25519(pkey->ameth->pkey_id)) {
|
||||
return X25519_BITS;
|
||||
} else if(ISX448(pkey->ameth->pkey_id)) {
|
||||
return X448_BITS;
|
||||
} else {
|
||||
return ED448_BITS;
|
||||
}
|
||||
}
|
||||
|
||||
static int ecx_security_bits(const EVP_PKEY *pkey)
|
||||
{
|
||||
if (IS25519(pkey->ameth->pkey_id)) {
|
||||
return X25519_SECURITY_BITS;
|
||||
} else {
|
||||
return X448_SECURITY_BITS;
|
||||
}
|
||||
}
|
||||
|
||||
static void ecx_free(EVP_PKEY *pkey)
|
||||
{
|
||||
if (pkey->pkey.ecx != NULL)
|
||||
OPENSSL_secure_clear_free(pkey->pkey.ecx->privkey, KEYLEN(pkey));
|
||||
OPENSSL_free(pkey->pkey.ecx);
|
||||
}
|
||||
|
||||
/* "parameters" are always equal */
|
||||
static int ecx_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ecx_key_print(BIO *bp, const EVP_PKEY *pkey, int indent,
|
||||
ASN1_PCTX *ctx, ecx_key_op_t op)
|
||||
{
|
||||
const ECX_KEY *ecxkey = pkey->pkey.ecx;
|
||||
const char *nm = OBJ_nid2ln(pkey->ameth->pkey_id);
|
||||
|
||||
if (op == KEY_OP_PRIVATE) {
|
||||
if (ecxkey == NULL || ecxkey->privkey == NULL) {
|
||||
if (BIO_printf(bp, "%*s<INVALID PRIVATE KEY>\n", indent, "") <= 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
if (BIO_printf(bp, "%*s%s Private-Key:\n", indent, "", nm) <= 0)
|
||||
return 0;
|
||||
if (BIO_printf(bp, "%*spriv:\n", indent, "") <= 0)
|
||||
return 0;
|
||||
if (ASN1_buf_print(bp, ecxkey->privkey, KEYLEN(pkey),
|
||||
indent + 4) == 0)
|
||||
return 0;
|
||||
} else {
|
||||
if (ecxkey == NULL) {
|
||||
if (BIO_printf(bp, "%*s<INVALID PUBLIC KEY>\n", indent, "") <= 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
if (BIO_printf(bp, "%*s%s Public-Key:\n", indent, "", nm) <= 0)
|
||||
return 0;
|
||||
}
|
||||
if (BIO_printf(bp, "%*spub:\n", indent, "") <= 0)
|
||||
return 0;
|
||||
|
||||
if (ASN1_buf_print(bp, ecxkey->pubkey, KEYLEN(pkey),
|
||||
indent + 4) == 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ecx_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
|
||||
ASN1_PCTX *ctx)
|
||||
{
|
||||
return ecx_key_print(bp, pkey, indent, ctx, KEY_OP_PRIVATE);
|
||||
}
|
||||
|
||||
static int ecx_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
|
||||
ASN1_PCTX *ctx)
|
||||
{
|
||||
return ecx_key_print(bp, pkey, indent, ctx, KEY_OP_PUBLIC);
|
||||
}
|
||||
|
||||
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, pkey->ameth->pkey_id, NULL, arg2, arg1,
|
||||
KEY_OP_PUBLIC);
|
||||
|
||||
case ASN1_PKEY_CTRL_GET1_TLS_ENCPT:
|
||||
if (pkey->pkey.ecx != NULL) {
|
||||
unsigned char **ppt = arg2;
|
||||
|
||||
*ppt = OPENSSL_memdup(pkey->pkey.ecx->pubkey, KEYLEN(pkey));
|
||||
if (*ppt != NULL)
|
||||
return KEYLEN(pkey);
|
||||
}
|
||||
return 0;
|
||||
|
||||
default:
|
||||
return -2;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static int ecd_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
|
||||
{
|
||||
switch (op) {
|
||||
case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
|
||||
/* We currently only support Pure EdDSA which takes no digest */
|
||||
*(int *)arg2 = NID_undef;
|
||||
return 2;
|
||||
|
||||
default:
|
||||
return -2;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static int ecx_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv,
|
||||
size_t len)
|
||||
{
|
||||
return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, priv, len,
|
||||
KEY_OP_PRIVATE);
|
||||
}
|
||||
|
||||
static int ecx_set_pub_key(EVP_PKEY *pkey, const unsigned char *pub, size_t len)
|
||||
{
|
||||
return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, pub, len,
|
||||
KEY_OP_PUBLIC);
|
||||
}
|
||||
|
||||
static int ecx_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv,
|
||||
size_t *len)
|
||||
{
|
||||
const ECX_KEY *key = pkey->pkey.ecx;
|
||||
|
||||
if (priv == NULL) {
|
||||
*len = KEYLENID(pkey->ameth->pkey_id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (key == NULL
|
||||
|| key->privkey == NULL
|
||||
|| *len < (size_t)KEYLENID(pkey->ameth->pkey_id))
|
||||
return 0;
|
||||
|
||||
*len = KEYLENID(pkey->ameth->pkey_id);
|
||||
memcpy(priv, key->privkey, *len);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ecx_get_pub_key(const EVP_PKEY *pkey, unsigned char *pub,
|
||||
size_t *len)
|
||||
{
|
||||
const ECX_KEY *key = pkey->pkey.ecx;
|
||||
|
||||
if (pub == NULL) {
|
||||
*len = KEYLENID(pkey->ameth->pkey_id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (key == NULL
|
||||
|| *len < (size_t)KEYLENID(pkey->ameth->pkey_id))
|
||||
return 0;
|
||||
|
||||
*len = KEYLENID(pkey->ameth->pkey_id);
|
||||
memcpy(pub, key->pubkey, *len);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = {
|
||||
EVP_PKEY_X25519,
|
||||
EVP_PKEY_X25519,
|
||||
0,
|
||||
"X25519",
|
||||
"OpenSSL X25519 algorithm",
|
||||
|
||||
ecx_pub_decode,
|
||||
ecx_pub_encode,
|
||||
ecx_pub_cmp,
|
||||
ecx_pub_print,
|
||||
|
||||
ecx_priv_decode,
|
||||
ecx_priv_encode,
|
||||
ecx_priv_print,
|
||||
|
||||
ecx_size,
|
||||
ecx_bits,
|
||||
ecx_security_bits,
|
||||
|
||||
0, 0, 0, 0,
|
||||
ecx_cmp_parameters,
|
||||
0, 0,
|
||||
|
||||
ecx_free,
|
||||
ecx_ctrl,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
ecx_set_priv_key,
|
||||
ecx_set_pub_key,
|
||||
ecx_get_priv_key,
|
||||
ecx_get_pub_key,
|
||||
};
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth = {
|
||||
EVP_PKEY_X448,
|
||||
EVP_PKEY_X448,
|
||||
0,
|
||||
"X448",
|
||||
"OpenSSL X448 algorithm",
|
||||
|
||||
ecx_pub_decode,
|
||||
ecx_pub_encode,
|
||||
ecx_pub_cmp,
|
||||
ecx_pub_print,
|
||||
|
||||
ecx_priv_decode,
|
||||
ecx_priv_encode,
|
||||
ecx_priv_print,
|
||||
|
||||
ecx_size,
|
||||
ecx_bits,
|
||||
ecx_security_bits,
|
||||
|
||||
0, 0, 0, 0,
|
||||
ecx_cmp_parameters,
|
||||
0, 0,
|
||||
|
||||
ecx_free,
|
||||
ecx_ctrl,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
ecx_set_priv_key,
|
||||
ecx_set_pub_key,
|
||||
ecx_get_priv_key,
|
||||
ecx_get_pub_key,
|
||||
};
|
||||
|
||||
static int ecd_size25519(const EVP_PKEY *pkey)
|
||||
{
|
||||
return ED25519_SIGSIZE;
|
||||
}
|
||||
|
||||
static int ecd_size448(const EVP_PKEY *pkey)
|
||||
{
|
||||
return ED448_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;
|
||||
int nid;
|
||||
|
||||
/* Sanity check: make sure it is ED25519/ED448 with absent parameters */
|
||||
X509_ALGOR_get0(&obj, &ptype, NULL, sigalg);
|
||||
nid = OBJ_obj2nid(obj);
|
||||
if ((nid != NID_ED25519 && nid != NID_ED448) || 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_sign25519(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_set25519(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;
|
||||
}
|
||||
|
||||
static int ecd_item_sign448(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
|
||||
X509_ALGOR *alg1, X509_ALGOR *alg2,
|
||||
ASN1_BIT_STRING *str)
|
||||
{
|
||||
/* Set algorithm identifier */
|
||||
X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL);
|
||||
if (alg2 != NULL)
|
||||
X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL);
|
||||
/* Algorithm identifier set: carry on as normal */
|
||||
return 3;
|
||||
}
|
||||
|
||||
static int ecd_sig_info_set448(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
|
||||
const ASN1_STRING *sig)
|
||||
{
|
||||
X509_SIG_INFO_set(siginf, NID_undef, NID_ED448, X448_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_size25519,
|
||||
ecx_bits,
|
||||
ecx_security_bits,
|
||||
|
||||
0, 0, 0, 0,
|
||||
ecx_cmp_parameters,
|
||||
0, 0,
|
||||
|
||||
ecx_free,
|
||||
ecd_ctrl,
|
||||
NULL,
|
||||
NULL,
|
||||
ecd_item_verify,
|
||||
ecd_item_sign25519,
|
||||
ecd_sig_info_set25519,
|
||||
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
ecx_set_priv_key,
|
||||
ecx_set_pub_key,
|
||||
ecx_get_priv_key,
|
||||
ecx_get_pub_key,
|
||||
};
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD ed448_asn1_meth = {
|
||||
EVP_PKEY_ED448,
|
||||
EVP_PKEY_ED448,
|
||||
0,
|
||||
"ED448",
|
||||
"OpenSSL ED448 algorithm",
|
||||
|
||||
ecx_pub_decode,
|
||||
ecx_pub_encode,
|
||||
ecx_pub_cmp,
|
||||
ecx_pub_print,
|
||||
|
||||
ecx_priv_decode,
|
||||
ecx_priv_encode,
|
||||
ecx_priv_print,
|
||||
|
||||
ecd_size448,
|
||||
ecx_bits,
|
||||
ecx_security_bits,
|
||||
|
||||
0, 0, 0, 0,
|
||||
ecx_cmp_parameters,
|
||||
0, 0,
|
||||
|
||||
ecx_free,
|
||||
ecd_ctrl,
|
||||
NULL,
|
||||
NULL,
|
||||
ecd_item_verify,
|
||||
ecd_item_sign448,
|
||||
ecd_sig_info_set448,
|
||||
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
ecx_set_priv_key,
|
||||
ecx_set_pub_key,
|
||||
ecx_get_priv_key,
|
||||
ecx_get_pub_key,
|
||||
};
|
||||
|
||||
static int pkey_ecx_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
|
||||
{
|
||||
return ecx_key_op(pkey, ctx->pmeth->pkey_id, NULL, NULL, 0, KEY_OP_KEYGEN);
|
||||
}
|
||||
|
||||
static int validate_ecx_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
|
||||
size_t *keylen,
|
||||
const unsigned char **privkey,
|
||||
const unsigned char **pubkey)
|
||||
{
|
||||
const ECX_KEY *ecxkey, *peerkey;
|
||||
|
||||
if (ctx->pkey == NULL || ctx->peerkey == NULL) {
|
||||
ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_KEYS_NOT_SET);
|
||||
return 0;
|
||||
}
|
||||
ecxkey = ctx->pkey->pkey.ecx;
|
||||
peerkey = ctx->peerkey->pkey.ecx;
|
||||
if (ecxkey == NULL || ecxkey->privkey == NULL) {
|
||||
ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_INVALID_PRIVATE_KEY);
|
||||
return 0;
|
||||
}
|
||||
if (peerkey == NULL) {
|
||||
ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_INVALID_PEER_KEY);
|
||||
return 0;
|
||||
}
|
||||
*privkey = ecxkey->privkey;
|
||||
*pubkey = peerkey->pubkey;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
|
||||
size_t *keylen)
|
||||
{
|
||||
const unsigned char *privkey, *pubkey;
|
||||
|
||||
if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
|
||||
|| (key != NULL
|
||||
&& X25519(key, privkey, pubkey) == 0))
|
||||
return 0;
|
||||
*keylen = X25519_KEYLEN;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
|
||||
size_t *keylen)
|
||||
{
|
||||
const unsigned char *privkey, *pubkey;
|
||||
|
||||
if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
|
||||
|| (key != NULL
|
||||
&& X448(key, privkey, pubkey) == 0))
|
||||
return 0;
|
||||
*keylen = X448_KEYLEN;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pkey_ecx_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
{
|
||||
/* Only need to handle peer key for derivation */
|
||||
if (type == EVP_PKEY_CTRL_PEER_KEY)
|
||||
return 1;
|
||||
return -2;
|
||||
}
|
||||
|
||||
const EVP_PKEY_METHOD ecx25519_pkey_meth = {
|
||||
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,
|
||||
pkey_ecx_derive25519,
|
||||
pkey_ecx_ctrl,
|
||||
0
|
||||
};
|
||||
|
||||
const EVP_PKEY_METHOD ecx448_pkey_meth = {
|
||||
EVP_PKEY_X448,
|
||||
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,
|
||||
pkey_ecx_derive448,
|
||||
pkey_ecx_ctrl,
|
||||
0
|
||||
};
|
||||
|
||||
static int pkey_ecd_digestsign25519(EVP_MD_CTX *ctx, unsigned char *sig,
|
||||
size_t *siglen, const unsigned char *tbs,
|
||||
size_t tbslen)
|
||||
{
|
||||
const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
|
||||
|
||||
if (sig == NULL) {
|
||||
*siglen = ED25519_SIGSIZE;
|
||||
return 1;
|
||||
}
|
||||
if (*siglen < ED25519_SIGSIZE) {
|
||||
ECerr(EC_F_PKEY_ECD_DIGESTSIGN25519, 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_digestsign448(EVP_MD_CTX *ctx, unsigned char *sig,
|
||||
size_t *siglen, const unsigned char *tbs,
|
||||
size_t tbslen)
|
||||
{
|
||||
const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
|
||||
|
||||
if (sig == NULL) {
|
||||
*siglen = ED448_SIGSIZE;
|
||||
return 1;
|
||||
}
|
||||
if (*siglen < ED448_SIGSIZE) {
|
||||
ECerr(EC_F_PKEY_ECD_DIGESTSIGN448, EC_R_BUFFER_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ED448_sign(sig, tbs, tbslen, edkey->pubkey, edkey->privkey, NULL,
|
||||
0) == 0)
|
||||
return 0;
|
||||
*siglen = ED448_SIGSIZE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pkey_ecd_digestverify25519(EVP_MD_CTX *ctx, const unsigned char *sig,
|
||||
size_t siglen, const unsigned char *tbs,
|
||||
size_t tbslen)
|
||||
{
|
||||
const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
|
||||
|
||||
if (siglen != ED25519_SIGSIZE)
|
||||
return 0;
|
||||
|
||||
return ED25519_verify(tbs, tbslen, sig, edkey->pubkey);
|
||||
}
|
||||
|
||||
static int pkey_ecd_digestverify448(EVP_MD_CTX *ctx, const unsigned char *sig,
|
||||
size_t siglen, const unsigned char *tbs,
|
||||
size_t tbslen)
|
||||
{
|
||||
const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
|
||||
|
||||
if (siglen != ED448_SIGSIZE)
|
||||
return 0;
|
||||
|
||||
return ED448_verify(tbs, tbslen, sig, edkey->pubkey, NULL, 0);
|
||||
}
|
||||
|
||||
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 || (const EVP_MD *)p2 == EVP_md_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_digestsign25519,
|
||||
pkey_ecd_digestverify25519
|
||||
};
|
||||
|
||||
const EVP_PKEY_METHOD ed448_pkey_meth = {
|
||||
EVP_PKEY_ED448, 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_digestsign448,
|
||||
pkey_ecd_digestverify448
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue