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 + -
显示快捷键?