File indexing completed on 2024-11-24 04:44:40
0001 /* 0002 * SPDX-FileCopyrightText: 2021 Volker Krause <vkrause@kde.org> 0003 * SPDX-License-Identifier: LGPL-2.0-or-later 0004 */ 0005 0006 #include "irmapublickey_p.h" 0007 0008 #include "openssl/bignum_p.h" 0009 0010 #include <QDebug> 0011 #include <QFile> 0012 #include <QXmlStreamReader> 0013 0014 // see https://pkg.go.dev/github.com/privacybydesign/gabi@v0.0.0-20210816093228-75a6590e506c/gabikeys#PublicKey 0015 0016 IrmaPublicKey::IrmaPublicKey() = default; 0017 0018 bool IrmaPublicKey::isValid() const 0019 { 0020 return N && Z && S && std::all_of(R.begin(), R.end(), [](const auto &r) { return r.get() != nullptr; }); 0021 } 0022 0023 // see https://github.com/minvws/gabi/blob/idemix_origin/sysparams.go#L21 0024 int IrmaPublicKey::LePrime() const 0025 { 0026 return 120; 0027 } 0028 0029 int IrmaPublicKey::Lh() const 0030 { 0031 return 256; 0032 } 0033 0034 int IrmaPublicKey::Lm() const 0035 { 0036 switch (BN_num_bits(N.get())) { 0037 case 1024: 0038 case 2048: 0039 return 256; 0040 case 4096: 0041 return 512; 0042 } 0043 return 0; 0044 } 0045 0046 int IrmaPublicKey::Lstatzk() const 0047 { 0048 switch (BN_num_bits(N.get())) { 0049 case 1024: 0050 return 80; 0051 case 2048: 0052 case 4096: 0053 return 128; 0054 } 0055 return 0; 0056 } 0057 0058 // and https://github.com/minvws/gabi/blob/idemix_origin/sysparams.go#L60 0059 int IrmaPublicKey::Le() const 0060 { 0061 return Lstatzk() + Lh() + Lm() + 5; 0062 } 0063 0064 int IrmaPublicKey::LeCommit() const 0065 { 0066 return LePrime() + Lstatzk() + Lh(); 0067 } 0068 0069 int IrmaPublicKey::LmCommit() const 0070 { 0071 return Lm() + Lstatzk() + Lh(); 0072 } 0073 0074 0075 IrmaPublicKey IrmaPublicKeyLoader::load(const QString &keyId) 0076 { 0077 IrmaPublicKey pk; 0078 0079 QFile pkFile(QLatin1String(":/org.kde.khealthcertificate/nl-coronacheck/keys/") + keyId + QLatin1String(".xml")); 0080 if (!pkFile.open(QFile::ReadOnly)) { 0081 qWarning() << "Failed to find IRMA public key:" << keyId; 0082 return pk; 0083 } 0084 0085 QXmlStreamReader reader(&pkFile); 0086 while (!reader.atEnd() && !reader.hasError()) { 0087 reader.readNextStartElement(); 0088 if (reader.name() == QLatin1String("n")) { 0089 pk.N = Bignum::fromDecimalString(reader.readElementText()); 0090 } 0091 else if (reader.name() == QLatin1String("Z")) { 0092 pk.Z = Bignum::fromDecimalString(reader.readElementText()); 0093 } 0094 else if (reader.name() == QLatin1String("S")) { 0095 pk.S = Bignum::fromDecimalString(reader.readElementText()); 0096 } 0097 else if (reader.name() == QLatin1String("Bases")) { 0098 const auto num = reader.attributes().value(QLatin1String("num")).toInt(); 0099 pk.R.reserve(num); 0100 } 0101 else if (reader.name().startsWith(QLatin1String("Base_"))) { 0102 pk.R.push_back(Bignum::fromDecimalString(reader.readElementText())); 0103 } 0104 } 0105 0106 return pk; 0107 }