asn.cpp

来自「NAT打洞」· C++ 代码 · 共 716 行 · 第 1/2 页

CPP
716
字号
/* 
   borZoi - An Elliptic Curve Cryptography Library

   Copyright (C) 2001 Anthony Mulcahy

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  

*/


#pragma warning(disable:4786) // for Visual C++
#include "borzoi.h"


//ansi-X9-62 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) 10045 }

OCTETSTR DER_Encode (unsigned long z);
unsigned long DER2UL (OCTETSTR der_rep);

OCTETSTR DER_Encode (BigInt z);
BigInt DER2BigInt (OCTETSTR der_rep);

OCTETSTR DER_Encode (F2M f);
F2M DER2F2M (OCTETSTR der_rep);

OCTETSTR DER_Encode (Point P);
Point DER2Point (OCTETSTR der_rep);

OCTETSTR DER_Encode (Curve C);
Curve DER2Curve (OCTETSTR der_rep);

OCTETSTR DER_Encode (OCTETSTR in);
OCTETSTR DER2OCTETSTR (OCTETSTR der_rep);

OCTETSTR DER_Encode (EC_Domain_Parameters dp);
EC_Domain_Parameters DER2ECDP (OCTETSTR der_rep);


OCTETSTR DER_Seq_Encode (OCTETSTR der_rep);

std::vector<OCTETSTR> DER_Seq_Decode (OCTETSTR in);

OCTETSTR DER_Seq_Encode (std::vector<OCTETSTR> in);

unsigned long DER_Extract_Length (OCTETSTR& der);

void DER_Insert_Length (OCTETSTR& der);


DER::DER (EC_Domain_Parameters dp) {
	v = DER_Encode (dp);
}


DER::DER (ECPubKey pk) {
	OCTETSTR algorithmidentifier;
     	// 06 Length (40*01+02+840+10045+02+01=)
	std::vector<OCTETSTR> a;

	OCTETSTR algorithm(9);
	algorithm[0] = 0x06; algorithm[1] = 0x07; algorithm[2] = 0x2A;
	algorithm[3] = 0x86; algorithm[4] = 0x48; algorithm[5] = 0xCE;
	algorithm[6] = 0x3D; algorithm[7] = 0x02; algorithm[8] = 0x01;
	a.push_back (algorithm); // version

	a.push_back (DER_Encode (pk.dp));

	algorithmidentifier = DER_Seq_Encode (a);
	std::vector<OCTETSTR> buf;
	buf.push_back (algorithmidentifier);

	OCTETSTR ecpoint = DER_Encode (pk.W);

	ecpoint.insert (ecpoint.begin (), 0x00);	
	if (ecpoint.size() > 127) {
		std::vector<OCTETSTR>::size_type size = ecpoint.size();
		OCTET no_octets = 0;
		while (size>0) {
			ecpoint.insert (ecpoint.begin (), size%0x100);
			size /= 0x100;
			no_octets++;
		}
		no_octets |= 0x80;
		ecpoint.insert (ecpoint.begin (), no_octets);	
	} else {
		ecpoint.insert (ecpoint.begin (), ecpoint.size ());	

	}
	ecpoint.insert (ecpoint.begin (), 0x03);	
	buf.push_back (ecpoint);

	v = DER_Seq_Encode (buf);
}


DER::DER (ECPrivKey sk) {
	std::vector<OCTETSTR> buf;

	buf.push_back (DER_Encode (1)); // version
	buf.push_back (DER_Encode (sk.s)); // private key
	buf.push_back (DER_Encode (sk.dp)); // EC domain parameters

	v = DER_Seq_Encode (buf);
}


DER::DER (ECDSA sig) {

	OCTETSTR Algorithmidentifier;
	std::vector<OCTETSTR> Algorithmidentifier_buf;
     	// 06 Length (40*01+02+840+10045+04+01=)
	OCTETSTR algorithm(9);
	algorithm[0] = 0x06; algorithm[1] = 0x07; algorithm[2] = 0x2A;
	algorithm[3] = 0x86; algorithm[4] = 0x48; algorithm[5] = 0xCE;
	algorithm[6] = 0x3D; algorithm[7] = 0x04; algorithm[8] = 0x01;
	Algorithmidentifier_buf.push_back (algorithm);
	Algorithmidentifier = DER_Seq_Encode (Algorithmidentifier_buf);

	OCTETSTR ECDSA_Sig_Value;
	std::vector<OCTETSTR> ECDSA_Sig_Value_buf;
	ECDSA_Sig_Value_buf.push_back (DER_Encode (sig.c)); // r in X9.62
	ECDSA_Sig_Value_buf.push_back (DER_Encode (sig.d)); // s in X9.62
	ECDSA_Sig_Value = DER_Seq_Encode (ECDSA_Sig_Value_buf);

	std::vector<OCTETSTR> buf;
	buf.push_back (Algorithmidentifier);
	buf.push_back (ECDSA_Sig_Value);

	v = DER_Seq_Encode (buf);
}


DER::DER (ECIES ct) {
	std::vector<OCTETSTR> buf;
	buf.push_back (DER(ct.V).v);
	buf.push_back (DER_Encode(ct.C));
	buf.push_back (DER_Encode(ct.T));

	v = DER_Seq_Encode (buf);
}


DER& DER::operator= (const DER& d) {
	if (this != &d)
		v = d.v;
	return *this;
}


std::ostream& DER::put (std::ostream&s) const {
	OCTETSTR::size_type i;
	for (i = 0; i < v.size(); i++) {
		//s.width(2); // 1.0.1 Incorrect, Remove
		//s.fill('0'); // 1.0.1 Incorrect, Remove
		s << v[i];
	}
	return s;
}


EC_Domain_Parameters DER::toECDP () {
	EC_Domain_Parameters dp = DER2ECDP (v);
	return dp;
}


ECPubKey DER::toECPubKey () {
	if (v[0] != 0x30)
		throw (borzoiException("DER_Decode_Public_Key: Not a Sequence"));

	std::vector<OCTETSTR> buf = DER_Seq_Decode (v);
	std::vector<OCTETSTR> a = DER_Seq_Decode (buf[0]);

	// buf[0]

     	// 06 Length (40*01+02+840+10045+02+01=)
	// a[0]
	// algorithm[0] = 0x06; algorithm[1] = 0x07; algorithm[2] = 0x2A;
	// algorithm[3] = 0x86; algorithm[4] = 0x48; algorithm[5] = 0xCE;
	// algorithm[6] = 0x3D; algorithm[7] = 0x02; algorithm[8] = 0x01;
	if (a[0][8] != 0x01)
		throw (borzoiException("DER_Decode_Public_Key: Invalid Algorithm"));

	// a[1]
	EC_Domain_Parameters dp = DER2ECDP (a[1]);

	// buf[1]
	OCTETSTR::iterator j=buf[1].begin();
	if (*j != 0x03)
		throw (borzoiException("ECPOINT Invalid"));
	else DER_Extract_Length (buf[1]); // Use this to delete the length OCTETs
	j=buf[1].begin(); buf[1].erase(j); // delete 0x00 OCTET
	Point ecpoint = DER2Point (buf[1]);

	ECPubKey pk (dp, ecpoint);
	return pk;
}


ECPrivKey DER::toECPrivKey () {
	if (v[0] != 0x30)
		throw (borzoiException("DER_Decode_Public_Key: Not a Sequence"));

	std::vector<OCTETSTR> buf = DER_Seq_Decode (v);

	if (DER2UL (buf[0]) != 0x01)
		throw (borzoiException("Unsupported Version"));
	BigInt s = DER2BigInt (buf[1]);
	EC_Domain_Parameters dp = DER2ECDP (buf[2]);

	ECPrivKey sk (dp, s);
	return sk;
}


ECDSA DER::toECDSA () {
	if (v[0] != 0x30)
		throw (borzoiException("DER::toECDSA: Not a Sequence"));

	std::vector<OCTETSTR> buf = DER_Seq_Decode (v);

	// buf[0]
	std::vector<OCTETSTR> a = DER_Seq_Decode (buf[0]);

    // 06 Length (40*01+02+840+10045+04+01=)
	// a[0]
	// algorithm[0] = 0x06; algorithm[1] = 0x07; algorithm[2] = 0x2A;
	// algorithm[3] = 0x86; algorithm[4] = 0x48; algorithm[5] = 0xCE;
	// algorithm[6] = 0x3D; algorithm[7] = 0x04; algorithm[8] = 0x01;
	if (a[0][8] != 0x01)
		throw (borzoiException("DER::toECDSA: Invalid Algorithm"));

	std::vector<OCTETSTR> b = DER_Seq_Decode (buf[1]);

	// c is r in X9.62, d is s in X9.62
	return ECDSA (DER2BigInt (b[0]), DER2BigInt (b[1]));
}


ECIES DER::toECIES () {
	std::vector<OCTETSTR> buf = DER_Seq_Decode (v);

	if (buf.size() != 3)
		throw (borzoiException("DER::toECIES: Invalid Sequence"));
	return ECIES (DER(buf[0]).toECPubKey(), DER2OCTETSTR(buf[1]), DER2OCTETSTR(buf[2]));
}


unsigned long DER2UL (OCTETSTR der_rep) {
	unsigned long length;
	if (der_rep[0] != 0x02)
		throw (borzoiException("Not an Integer"));
	else length = DER_Extract_Length (der_rep);

	unsigned long z = 0;
	for (unsigned long i=0; i<length; i++) {
		z *= 0x100;
		z += der_rep[i];
	}
	return z;
}


F2M DER2F2M (OCTETSTR der_rep) {
	F2X x;
	unsigned long k=0;

	unsigned long length;
	if (der_rep[0] != 0x04)
		throw (borzoiException("Not an Octet String"));
	else length = DER_Extract_Length (der_rep);

	for (unsigned long i=0; i<length; i++) {
		if (der_rep[length-1-i]&1)
			x.setCoeff (k, 1);
		k++;
		if (der_rep[length-1-i]&2)
			x.setCoeff (k, 1);
		k++;
		if (der_rep[length-1-i]&4)
			x.setCoeff (k, 1);
		k++;
		if (der_rep[length-1-i]&8)
			x.setCoeff (k, 1);
		k++;
		if (der_rep[length-1-i]&16)
			x.setCoeff (k, 1);
		k++;
		if (der_rep[length-1-i]&32)
			x.setCoeff (k, 1);
		k++;
		if (der_rep[length-1-i]&64)
			x.setCoeff (k, 1);
		k++;
		if (der_rep[length-1-i]&128)
			x.setCoeff (k, 1);
		k++;
	}

	F2M f = F2M (x);
	return f;
}


BigInt DER2BigInt (OCTETSTR der_rep) {
	unsigned long length;
	if (der_rep[0] != 0x02)
		throw (borzoiException("Not an Integer"));
	else length = DER_Extract_Length (der_rep);

	BigInt z;
	for (unsigned long i=0; i<length; i++) {
		z *= BigInt (0x10);
		z *= BigInt (0x10);
		z += BigInt (der_rep[i]);
	}
	return z;
}


Point DER2Point (OCTETSTR der_rep) {
	unsigned long length;
	if (der_rep[0] != 0x04)
		throw (borzoiException("Not an Octet String"));
	else length = DER_Extract_Length (der_rep);

	F2X x, y;
	unsigned long k=0;
	for (unsigned long i=(length-1)/2; i>0; i--) {
		if (der_rep[i]&1)
			x.setCoeff (k, 1);
		if (der_rep[i+(length-1)/2]&1)
			y.setCoeff (k, 1);
		k++;
		if (der_rep[i]&2)
			x.setCoeff (k, 1);
		if (der_rep[i+(length-1)/2]&2)
			y.setCoeff (k, 1);
		k++;
		if (der_rep[i]&4)
			x.setCoeff (k, 1);
		if (der_rep[i+(length-1)/2]&4)
			y.setCoeff (k, 1);
		k++;
		if (der_rep[i]&8)
			x.setCoeff (k, 1);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?