On 2006.12.27 at 09:57:30 +0100, Andy Polyakov wrote:
> line #248 still reads as 'if(0)'. I'll have alook at the code, but there
> might be need for test case, so could you provide sequence of commands
> to reproduce the problem [or program if it was one].
Here small test programm is attached.
It should be compiled with few object files from ccgost engine.
gostectest: gostectest.o gost2001.o gost_sign.o gost_params.o e_gost_err.o
$(CC) -o $@ $(LDFLAGS) $+ -lcrypto
There is output from machine that works correctly:
Computing public key for private key
55441196065363246126355624130324183196576709222340016572108097750006097525544
Computed public key
X=FD21C21AB0DC84C154F3D218E9040BEE64FFF48BDFF814B232295B09D0DF72E4
Y=5026DEC9AC4F07061A2A01D7A2307E0659239A82A95862DF86041D1458E45049
Computed test signature
r=74E939C637A79A5B7E39DC15976BEFB324ACDB74E2FA8D434ABA0DA9EBF8DE8F
s=1F3DE74B3906D73920A5B332F5E4DEDF8FDAB3AC8DB157DCE780F3DB4F1A6B0B
Verifying test signature: 1
There is output which I get on machine where bug triggers on
Computing public key for private key
55441196065363246126355624130324183196576709222340016572108097750006097525544
Computed public key
X=B31388A5BC006BF9992CD0709F7DDE33D1542B737F1745F92CD14AD093A2B6D0
Y=646C27DAA450CFBFCB7BE199EAD69ABDE706C427DF0F6363CC3DC6CF714616E4
Computed test signature
r=33C0E8D12FE8444774CF4FDC692F71C4F5070F5228CC2493AB45BDCCA345F7C
s=477AE611BAFDBE639BD934CD4FB3E433BD059CC5BABB8E6A0E17C8C603A0A347
Verifying test signature: 0
Running this program essentially narrows problem down to
function gost2001_compute_public (although, same problem triggers on in _sign
and _verify too)
which consists of (error reporting removed)
int gost2001_compute_public(EC_KEY *ec)
{
const EC_GROUP *group = EC_KEY_get0_group(ec);
EC_POINT *pub_key=NULL;
const BIGNUM *priv_key=NULL;
BN_CTX *ctx=NULL;
int ok=0;
ctx=BN_CTX_new();
BN_CTX_start(ctx);
priv_key=EC_KEY_get0_private_key(ec);
pub_key = EC_POINT_new(group);
EC_POINT_mul(group,pub_key,priv_key,NULL,NULL,ctx);
EC_KEY_set_public_key(ec,pub_key);
ok = 256;
return ok;
}
It seems that there is nothing to fail except EC_POINT_mul function,
and only difference with native tests is usage of RFC 4357 EC_group.
/**********************************************************************
* ectest.c *
* Copyright (c) 2005-2006 Cryptocom LTD *
* This file is distributed under same license as OpenSSL *
* *
* GOST R 34.10-2001 algorithm test program *
* Requires libcrypto from OpenSSL 0.9.8 for compilation *
* *
**********************************************************************/
#include <stdio.h>
#include "gost_lcl.h"
#include "gost_params.h"
/* Test example from GOST 34.10 - 2001 */
/* Digest value */
unsigned char dgst[]={
0xE5, 0x3E, 0x04, 0x2B, 0x67, 0xE6, 0xEC, 0x67,
0x8E, 0x2E, 0x02, 0xB1, 0x2A, 0x03, 0x52, 0xCE,
0x1F, 0xC6, 0xEE, 0xE0, 0x52, 0x9C, 0xC0, 0x88,
0x11, 0x9A, 0xD8, 0x72, 0xB3, 0xC1, 0xFB, 0x2D};
/* Simulated random generation, which does always produce value from
* example */
int BN_rand_range(BIGNUM *k,BIGNUM *range) {
BN_hex2bn(&k,"77105C9B20BCD3122823C8CF6FCC7B956DE33814E95B7Fe64FED924594DCEAB3");
return 1;
}
/* Private key from example */
const char *privkey ="55441196065363246126355624130324183196576709222340016572108097750006097525544";
int main(int argc, char **argv) {
EC_KEY *pkey;
BIGNUM *pk = NULL,*X=NULL,*Y=NULL;
const EC_POINT *pub_key;
const EC_GROUP *group;
int i;
DSA_SIG *sig;
pkey = EC_KEY_new();
/* Typically engine assigns NIDs to parameter sets dynamically upon
* registartion of OIDs, but we don't need full engine
* initialization here, so just assign arbitrary integers */
/* Set GOST test parameters */
fill_GOST2001_params(pkey,NID_id_GostR3410_2001_CryptoPro_A_ParamSet);
/* Set private key */
BN_dec2bn(&pk,privkey);
EC_KEY_set_private_key(pkey,pk);
/* Compute public key. This is first test, that we correctly derive
* public key from private */
printf("Computing public key for private key %s\n",privkey);
gost2001_compute_public(pkey);
printf("Computed public key\n");
/* Output public key */
pub_key = EC_KEY_get0_public_key(pkey);
group = EC_KEY_get0_group(pkey);
X=BN_new(); Y=BN_new();
EC_POINT_get_affine_coordinates_GFp(group,pub_key,X,Y,NULL);
printf("\nX=");BN_print_fp(stdout,X);
printf("\nY=");BN_print_fp(stdout,Y);
printf("\n");
/* Compute signature of test digest */
sig=gost2001_do_sign(dgst,32,pkey);
printf("Computed test signature\nr=");
/* Output it */
BN_print_fp(stdout,sig->r);
printf("\ns=");
BN_print_fp(stdout,sig->s);
printf("\n");
/* And verify */
printf("Verifying test signature: %d\n",
gost2001_do_verify(dgst,32,sig,pkey));
return 0;
}