Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simple scheme for a crytopgraphic data product #1346

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions Blinding/inc/BigNumber.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Ed Callaghan
// Interface for a large number; stored as a string, to be manipulated with gmp
// August 2024

#ifndef BigNumber_hh
#define BigNumber_hh

#include <string>

namespace mu2e{
class BigNumber{
public:
BigNumber() = default;
BigNumber(std::string);
const char* Buffer() const;
const std::string& String() const;
bool IsZero() const;
bool operator== (const BigNumber&) const;
protected:
std::string _rep;
private:
/**/
};
} // namespace mu2e

#endif
45 changes: 45 additions & 0 deletions Blinding/inc/GMPRoutines.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Ed Callaghan
// A collection of routines using gmp functions and types
// August 2024

#ifndef GMPRoutines_hh
#define GMPRoutines_hh

#include <gmp.h>

namespace mu2e{
namespace gmp{
// test if x is a quadratic resiue of N = p * q
bool is_quadratic_residue(mpz_t x,
const mpz_t& p,
const mpz_t& q,
const mpz_t& N);

// identify a non-quadratic residue of N = p * q
void sample_nonresidue(mpz_t x,
const mpz_t& p,
const mpz_t& q,
const mpz_t& N,
gmp_randstate_t state);

// identify x s.t. x == 1 (mod N)
void sample_unit_modulo(mpz_t x,
const mpz_t& N,
gmp_randstate_t state);

// apply Goldwasser-Micali encryption to a single bit
void gm_encrypt(mpz_t encrypted,
unsigned int set,
const mpz_t& x,
const mpz_t& N,
gmp_randstate_t state);

// apply Goldwasser-Micali decryption for a single bit; N = p * q
unsigned int gm_decrypt(mpz_t encrypted,
const mpz_t& p,
const mpz_t& q,
const mpz_t& N);
} // namespace gmp
} // namespace mu2e

#endif
31 changes: 31 additions & 0 deletions Blinding/src/BigNumber.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Ed Callaghan
// Interface for a large number; stored as a string, to be manipulated with gmp
// August 2024

#include "Offline/Blinding/inc/BigNumber.hh"

namespace mu2e{
BigNumber::BigNumber(std::string rep): _rep(rep){
/**/
}

const char* BigNumber::Buffer() const{
auto rv = _rep.c_str();
return rv;
}

const std::string& BigNumber::String() const{
auto& rv = _rep;
return rv;
}

bool BigNumber::IsZero() const{
auto rv = (_rep == "0");
return rv;
}

bool BigNumber::operator== (const BigNumber& rhs) const{
auto rv = (_rep == rhs.String());
return rv;
}
} // namespace mu2e
69 changes: 69 additions & 0 deletions Blinding/src/BigNumberChecker_module.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Ed Callaghan
// Compare two BigNumbers for equality; useful for validating en-/de-cryption
// August 2024

// stl
#include <string>

// art
#include "art/Framework/Core/EDAnalyzer.h"
#include "art/Framework/Principal/Event.h"

// cetlib_except
#include "cetlib_except/exception.h"

// fhiclcpp
#include "fhiclcpp/types/Atom.h"
#include "fhiclcpp/types/Comment.h"
#include "fhiclcpp/types/Name.h"

// mu2e
#include "Offline/Blinding/inc/BigNumber.hh"
#include "Offline/Blinding/inc/GMPRoutines.hh"

namespace mu2e{
class BigNumberChecker: public art::EDAnalyzer{
public:
struct Config{
fhicl::Atom<art::InputTag> lhs_tag{
fhicl::Name("BigNumber_a"),
fhicl::Comment("art::InputTag of BigNumber to compare to")
};
fhicl::Atom<art::InputTag> rhs_tag{
fhicl::Name("BigNumber_b"),
fhicl::Comment("art::InputTag of BigNumber to compare")
};
};

using Parameters = art::EDAnalyzer::Table<Config>;
BigNumberChecker(const Parameters&);
protected:
art::InputTag _lhs_tag;
art::InputTag _rhs_tag;
private:
void analyze(const art::Event&);
};

BigNumberChecker::BigNumberChecker(const Parameters& cfg):
art::EDAnalyzer(cfg),
_lhs_tag(cfg().lhs_tag()),
_rhs_tag(cfg().rhs_tag()){
/**/
}

void BigNumberChecker::analyze(const art::Event& event){
// locate BigNumbers
auto lhs_handle = event.getValidHandle<BigNumber>(_lhs_tag);
auto rhs_handle = event.getValidHandle<BigNumber>(_rhs_tag);

auto lhs = *lhs_handle;
auto rhs = *rhs_handle;
if (lhs != rhs){
std::string msg = "BigNumber mismatch: "
+ lhs.String() + " != " + rhs.String();
throw cet::exception("BigNumberChecker") << msg << std::endl;
}
}
} // namespace mu2e

DEFINE_ART_MODULE(mu2e::BigNumberChecker);
53 changes: 53 additions & 0 deletions Blinding/src/BigNumberProducer_module.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Ed Callaghan
// Produce constant BigNumbers
// August 2024

// stl
#include <string>

// art
#include "art/Framework/Core/EDProducer.h"
#include "art/Framework/Principal/Event.h"

// cetlib_except
#include "cetlib_except/exception.h"

// fhiclcpp
#include "fhiclcpp/types/Atom.h"
#include "fhiclcpp/types/Comment.h"
#include "fhiclcpp/types/Name.h"

// mu2e
#include "Offline/Blinding/inc/BigNumber.hh"

namespace mu2e{
class BigNumberProducer: public art::EDProducer{
public:
struct Config{
fhicl::Atom<std::string> value{
fhicl::Name("value"),
fhicl::Comment("Value to embed")
};
};

using Parameters = art::EDProducer::Table<Config>;
BigNumberProducer(const Parameters&);
protected:
std::string _digits;
private:
void produce(art::Event&);
};

BigNumberProducer::BigNumberProducer(const Parameters& config):
art::EDProducer(config),
_digits(config().value()){
this->produces<BigNumber>();
}

void BigNumberProducer::produce(art::Event& event){
auto product = std::make_unique<BigNumber>(_digits);
event.put(std::move(product));
}
} // namespace mu2e

DEFINE_ART_MODULE(mu2e::BigNumberProducer);
90 changes: 90 additions & 0 deletions Blinding/src/GMPRoutines.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// Ed Callaghan
// A collection of routines using gmp functions and types
// August 2024

#include "Offline/Blinding/inc/GMPRoutines.hh"

namespace mu2e{
namespace gmp{
// test if x is a quadratic resiue of N = p * q
bool is_quadratic_residue(mpz_t x,
const mpz_t& p,
const mpz_t& q,
const mpz_t& N){
mpz_t gcd;
mpz_init(gcd);

mpz_gcd(gcd, x, N);
int lp = mpz_legendre(x, p);
int lq = mpz_legendre(x, q);

bool rv = true;
rv &= (mpz_cmp_si(gcd, 1) == 0);
rv &= (lp == 1);
rv &= (lq == 1);

mpz_clear(gcd);
return rv;
}

// identify a non-quadratic residue of N = p * q
void sample_nonresidue(mpz_t x,
const mpz_t& p,
const mpz_t& q,
const mpz_t& N,
gmp_randstate_t state){
mpz_set(x, N);

do{
mpz_urandomm(x, state, N);
} while (is_quadratic_residue(x, p, q, N));
}

// identify x s.t. x == 1 (mod N)
void sample_unit_modulo(mpz_t x,
const mpz_t& N,
gmp_randstate_t state){
mpz_set(x, N);

mpz_t gcd;
mpz_init_set_ui(gcd, 0);
while (mpz_cmp_ui(gcd, 1) != 0){
mpz_urandomm(x, state, N);
mpz_gcd(gcd, x, N);
}
mpz_clear(gcd);
}

// apply Goldwasser-Micali encryption to a single bit
void gm_encrypt(mpz_t encrypted,
unsigned int set,
const mpz_t& x,
const mpz_t& N,
gmp_randstate_t state){
mpz_t y;
mpz_init(y);
sample_unit_modulo(y, N, state);

mpz_t rest;
mpz_init(rest);
mpz_pow_ui(rest, x, set);
mpz_mul(encrypted, y, y);
mpz_mul(encrypted, encrypted, rest);
mpz_mod(encrypted, encrypted, N);

mpz_clears(y, rest, NULL);
}

// apply Goldwasser-Micali decryption for a single bit; N = p * q
unsigned int gm_decrypt(mpz_t encrypted,
const mpz_t& p,
const mpz_t& q,
const mpz_t& N){
unsigned int rv = 1;
if (is_quadratic_residue(encrypted, p, q, N)){
rv = 0;
}
return rv;
}
} // namespace gmp
} // namespace mu2e
Loading