Commit e016c5cd authored by casualet's avatar casualet

init

parents
OBJDIR := obj
TOP := $(shell echo $${PWD-`pwd`})
CXX := g++
AR := ar
## -g -O0 -> -O2
CXXFLAGS := -g -O0 -fno-strict-aliasing -fno-rtti -fwrapv -fPIC \
-Wall -Werror -Wpointer-arith -Wendif-labels -Wformat=2 \
-Wextra -Wmissing-noreturn -Wwrite-strings -Wno-unused-parameter \
-Wno-deprecated \
-Wmissing-declarations -Woverloaded-virtual \
-Wunreachable-code -D_GNU_SOURCE -std=c++0x -I$(TOP)
LDFLAGS := -L$(TOP)/$(OBJDIR) -Wl,--no-undefined
## Copy conf/config.mk.sample to conf/config.mk and adjust accordingly.
include conf/config.mk
## Use RPATH only for debug builds; set RPATH=1 in config.mk.
ifeq ($(RPATH),1)
LDRPATH := -Wl,-rpath=$(TOP)/$(OBJDIR) -Wl,-rpath=$(TOP)
endif
CXXFLAGS += -I$(MYBUILD)/include \
-I$(MYSRC)/include \
-I$(MYSRC)/sql \
-I$(MYSRC)/regex \
-I$(MYBUILD)/sql \
-DHAVE_CONFIG_H -DMYSQL_SERVER -DEMBEDDED_LIBRARY -DDBUG_OFF \
-DMYSQL_BUILD_DIR=\"$(MYBUILD)\"
LDFLAGS += -lpthread -lrt -ldl -lcrypt -lreadline
## To be populated by Makefrag files
OBJDIRS :=
.PHONY: all
all:
.PHONY: install
install:
.PHONY: clean
clean:
rm -rf $(OBJDIR)
.PHONY: doc
doc:
doxygen CryptDBdoxgen
.PHONY: whitespace
whitespace:
find . -name '*.cc' -o -name '*.hh' -type f -exec sed -i 's/ *$//' '{}' ';'
.PHONY: always
always:
# Eliminate default suffix rules
.SUFFIXES:
# Delete target files if there is an error (or make is interrupted)
.DELETE_ON_ERROR:
# make it so that no intermediate .o files are ever deleted
.PRECIOUS: %.o
$(OBJDIR)/%.o: %.cc
@mkdir -p $(@D)
$(CXX) -MD $(CXXFLAGS) -c $< -o $@
echo "11111111111111111111111"
$(OBJDIR)/%.o: $(OBJDIR)/%.cc
@mkdir -p $(@D)
$(CXX) -MD $(CXXFLAGS) -c $< -o $@
echo "2222222222222222222222"
include crypto/Makefrag
include parser/Makefrag
include main/Makefrag
#include test/Makefrag
include util/Makefrag
include udf/Makefrag
include mysqlproxy/Makefrag
#include tools/import/Makefrag
#include tools/learn/Makefrag
#include scripts/Makefrag
$(OBJDIR)/.deps: $(foreach dir, $(OBJDIRS), $(wildcard $(OBJDIR)/$(dir)/*.d))
@mkdir -p $(@D)
perl mergedep.pl $@ $^
echo "after merge"
-include $(OBJDIR)/.deps
The source code for CryptDB is licensed under the terms of the GPL v3
license, unless otherwise noted (such as in the case of third-party
components and libraries):
CryptDB 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 3 of the License, or
(at your option) any later version.
CryptDB 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.
A copy of the GNU General Public License is included with CryptDB,
under doc/gpl-3.txt. Alternatively, see <http://www.gnu.org/licenses/>.
# CryptdbModify
Cryptdb originated from MIT. This is a modified version try to add new features and fix bugs we meet in our environment.
Introduction to the features included will be posted at yiwenshao.github.io.
To deploy this version, you need.
1. compile MySQL5.5 with the following command
```
mkdir build
cd build
export CXX=g++-4.7
cmake -DWITH_EMBEDDED_SERVER=on -DENABLE_DTRACE=off ..
make
```
2. set MySQL-SRC in conf/config.mk
3. have g++-4.7 and use make to compile
4. install MySQL-proxy
If you meet any problems installing it, contact me via shaoyiwenetATgmailDotcom.
This diff is collapsed.
create database tdb;
use tdb;
create table student (id varchar(20),name varchar(20));
insert into student values("1","shao");
insert into student values("2","zhao");
select * from student;
create database tdb;
use tdb;
create table student (id integer,name varchar(20),city integer);
insert into student values(1,"sdadsakld",2222);
insert into student values(222,"dadlsakdjsla",21211);
insert into student values(333,"slkxjlkcjsal",45454);
insert into student values(4444,"dddkljlksajs",65657);
insert into student values(5555,"eejwklejiowiow",7677887);
select * from student;
create database tdb3;
use tdb3;
create table student (id integer,name varchar(20));
insert into student values(1,"shalkdjsaflkdjxljfelwo");
insert into student values(2,"dafdksalfdkjsaao");
insert into student values(3,"shewlrejkwl;ruejiojldksjfdsao");
insert into student values(4,"sdfdsafdslajao");
insert into student values(5,"shaxljkdl;fjdksalujeiowjaqi;ewasao");
insert into student values(6,"shafdsafldsjakfldsalew;joifnmof;newiojro");
select * from student;
quit
find -name "*.cc" -o -name "*.hh" -o -name "*.tt" -o -name "*.c" -o -name "*.h" -o -name "*.cpp" > cscope.files
cscope -R -b -i cscope.files
-- MySQL dump 10.13 Distrib 5.7.17, for Linux (x86_64)
--
-- Host: localhost Database: tdb
-- ------------------------------------------------------
-- Server version 5.7.17-0ubuntu0.16.04.1-log
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `table_XSMHFHVBSI`
--
DROP TABLE IF EXISTS `table_XSMHFHVBSI`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `table_XSMHFHVBSI` (
`VJXMJSLTRKoEq` varbinary(48) DEFAULT NULL,
`MQEBZJIUNBoOrder` bigint(20) unsigned NOT NULL,
`cdb_saltXEUHERMBIR` bigint(8) unsigned DEFAULT NULL,
PRIMARY KEY (`MQEBZJIUNBoOrder`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `table_XSMHFHVBSI`
--
LOCK TABLES `table_XSMHFHVBSI` WRITE;
/*!40000 ALTER TABLE `table_XSMHFHVBSI` DISABLE KEYS */;
INSERT INTO `table_XSMHFHVBSI` VALUES ('@\\Z\6º\b g \nK\1,\~F',13302528688661037668,9478239721323719808);
/*!40000 ALTER TABLE `table_XSMHFHVBSI` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2017-02-20 10:05:18
-- MySQL dump 10.13 Distrib 5.7.17, for Linux (x86_64)
--
-- Host: localhost Database: tdb
-- ------------------------------------------------------
-- Server version 5.7.17-0ubuntu0.16.04.1-log
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `table_NJEPWCGNHM`
--
DROP TABLE IF EXISTS `table_NJEPWCGNHM`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `table_NJEPWCGNHM` (
`GDXCBIOGHCoEq` bigint(20) unsigned DEFAULT NULL,
`ZUODMKIUXPoOrder` bigint(20) unsigned DEFAULT NULL,
`GNYQGOSSNDoADD` varbinary(256) DEFAULT NULL,
`cdb_saltQGHROCLZLL` bigint(8) unsigned DEFAULT NULL,
`QTREWFOEZNoEq` varbinary(64) DEFAULT NULL,
`WICWYJKSDYoOrder` bigint(20) unsigned DEFAULT NULL,
`cdb_saltFWIDYLNMRX` bigint(8) unsigned DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `table_NJEPWCGNHM`
--
LOCK TABLES `table_NJEPWCGNHM` WRITE;
/*!40000 ALTER TABLE `table_NJEPWCGNHM` DISABLE KEYS */;
INSERT INTO `table_NJEPWCGNHM` VALUES (4830019261483347505,2324979638922462221,0x530FB1393394F932792FF90FE3CF74A3E7942CA5069AB58F9A93A356ECE2A02F897E9A3AF3416F4BF4CB6BAE54F8C8280BE3B5B3AE10B9B3CEC3C1BCD464E117DE39E7BBF7B2F61BD273352709851913348D2407F785493937DDFC3911EF7ED1D917D20A3ED00EB753976ACEA2F5906FE14243641DA4B6572919600758795A8B9C73694CB5219B59C20A9046B002FD08C34A790311BAF13D373E741979417EFBB7832CE4D603DB21D883027DA21A5E8451A6ACA295B41CA8EEB12B323401E44FB41A45B0B59A631EC8332630550B0879757AFC4A919B45C16D1A46DA1DE2B30A94E270964E8C9B87BCC0C0EA00EAB7A7F523CE123EE39064A5F290C05125FF3E,211794394337017064,0x5B5B095C18ED07D1586009433BB751F95E44F4378ABC217B9661D3B98C0948C0614872111EBD6EF70BFE98495A9F33FE,8074842047049308959,2009773872918125969);
/*!40000 ALTER TABLE `table_NJEPWCGNHM` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2017-02-08 15:51:22
-- MySQL dump 10.13 Distrib 5.7.17, for Linux (x86_64)
--
-- Host: localhost Database: tdb2
-- ------------------------------------------------------
-- Server version 5.7.17-0ubuntu0.16.04.1-log
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `table_NJEPWCGNHM`
--
DROP TABLE IF EXISTS `table_NJEPWCGNHM`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `table_NJEPWCGNHM` (
`GDXCBIOGHCoEq` bigint(20) unsigned DEFAULT NULL,
`ZUODMKIUXPoOrder` bigint(20) unsigned DEFAULT NULL,
`GNYQGOSSNDoADD` varbinary(256) DEFAULT NULL,
`cdb_saltQGHROCLZLL` bigint(8) unsigned DEFAULT NULL,
`QTREWFOEZNoEq` varbinary(64) DEFAULT NULL,
`WICWYJKSDYoOrder` bigint(20) unsigned DEFAULT NULL,
`cdb_saltFWIDYLNMRX` bigint(8) unsigned DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `table_NJEPWCGNHM`
--
LOCK TABLES `table_NJEPWCGNHM` WRITE;
/*!40000 ALTER TABLE `table_NJEPWCGNHM` DISABLE KEYS */;
INSERT INTO `table_NJEPWCGNHM` VALUES (4830019261483347505,2324979638922462221,'S932y/\\t\,V\\/~:AoK\kT\( 㵳\\\d\\9\\s5\' 4$I97\9\~\\\\n>\Sj΢o\BCdW)`XyZsiL!Y\\nF\Jy=7>tyA~,\\\!؃}\Z^Q\+24\O\ZEc\3&0U yuzJEm\ZF\\\n\pN\\0귧#\>\dQ%>',211794394337017064,'[[ \\\\X` C;Q^D7!{aӹ HaHrn IZ3',8074842047049308959,2009773872918125969);
/*!40000 ALTER TABLE `table_NJEPWCGNHM` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2017-02-08 15:55:08
This diff is collapsed.
a=`cat all`
final=""
arr=($a)
for item in ${arr[@]};do
final+=" "
final+=${item}
done
echo ${final}
This diff is collapsed.
set softtabstop=4
set expandtab
set number
# see http://uncrustify.sourceforge.net/default.cfg
newlines = lf
input_tab_size = 8
indent_columns = 4
indent_with_tabs = 0
indent_class = true
indent_access_spec = 2
nl_after_access_spec = 1
cmt_width = 78
code_width = 78
nl_max = 2
nl_before_throw = add
nl_func_type_name = add
nl_fdef_brace = add
../conf/dot.vimrc
\ No newline at end of file
This diff is collapsed.
#pragma once
/*
* BasicCrypto.h
*
* Basic symmetric key crypto.
*/
#include <map>
#include <string>
#include <vector>
#include <stdio.h>
#include <openssl/sha.h>
#include <openssl/rand.h>
#include <openssl/aes.h>
#include <openssl/evp.h>
#include <openssl/rsa.h>
#include <crypto/prng.hh>
#include <util/onions.hh>
std::string getLayerKey(const AES_KEY * const mKey,
std::string uniqueFieldName, SECLEVEL l);
AES_KEY * getKey(const std::string & key);
/**
* Returns the key corresponding to the security level given for some
* master key and some unique field name. Result will be AES_KEY_SIZE
* long.
*/
std::string getKey(const AES_KEY * const mkey,
const std::string &uniqueFieldName, SECLEVEL sec);
AES_KEY * get_AES_KEY(const std::string &key);
AES_KEY * get_AES_enc_key(const std::string & key);
AES_KEY * get_AES_dec_key(const std::string & key);
bool rounded_len(unsigned long len, uint block_size, bool dopad,
unsigned long *const out);
std::string marshallKey(const std::string &key);
//std::string unmarshallKey(const std::string &key);
std::vector<unsigned char>
getXorVector(size_t len, const AES_KEY * key, uint64_t salt);
std::string
encrypt_AES(const std::string & plaintext, const AES_KEY * key, uint64_t salt);
std::string
decrypt_AES(const std::string & ciphertext, const AES_KEY * key, uint64_t salt);
std::string
encrypt_AES_CBC(const std::string &ptext, const AES_KEY * enckey, std::string salt, bool pad = true);
std::string
decrypt_AES_CBC(const std::string &ctext, const AES_KEY * deckey, std::string salt, bool pad = true);
//only works for padding unit < 255 bytes
//std::vector<unsigned char> pad(std::vector<unsigned char> data, unsigned int unit);
//std::vector<unsigned char> unpad(std::vector<unsigned char> data);
std::string
encrypt_AES_CMC(const std::string &ptext, const AES_KEY * enckey, bool dopad = true);
std::string
decrypt_AES_CMC(const std::string &ctext, const AES_KEY * deckey, bool dopad = true);
//**** Public Key Cryptosystem (PKCS) *****//
typedef RSA PKCS;
const unsigned int PKCS_bytes_size = 256; //this is the size in
// openssl
//generates a new key
void generateKeys(PKCS * & pk, PKCS * & sk);
//marshalls a key
//if ispk is true, it returns the binary of the public key and sets let to
// the length returned
//is !ispk, it does the same for secret key
std::string marshallKey(PKCS * mkey, bool ispk);
//from a binary key of size keylen, it returns a public key if ispk, else
// a secret key
PKCS * unmarshallKey(const std::string &key, bool ispk);
//using key, it encrypts the data in from of size fromlen
//the result is len long
std::string encrypt(PKCS * key, const std::string &from);
//using key, it decrypts data at fromcipher, and returns the decrypted
// value
std::string decrypt(PKCS * key, const std::string &fromcipher);
//frees memory allocated by this keyb
void freeKey(PKCS * key);
/*
* ECJoin.cpp
*
*/
#include <crypto/ECJoin.hh>
#include <util/cryptdb_log.hh>
#include <util/util.hh>
using namespace std;
static EC_POINT *
my_EC_POINT_new(EC_GROUP * group) {
EC_POINT* point = EC_POINT_new(group);
throw_c(point, "could not create point");
return point;
}
static BIGNUM *
my_BN_new() {
BIGNUM* num = BN_new();
throw_c(num, "could not create BIGNUM");
return num;
}
static BIGNUM *
my_BN_mod(const BIGNUM * a, const BIGNUM * n, BN_CTX * bn_ctx) {
BIGNUM * res = my_BN_new();
BN_mod(res, a, n, bn_ctx);
throw_c(res, "failed to compute mod");
return res;
}
static EC_POINT *
str2Point(const EC_GROUP * group, const string & indata) {
EC_POINT * point = EC_POINT_new(group);
throw_c(EC_POINT_oct2point(group, point, (const unsigned char *)indata.data(), indata.length(), NULL),
"cannot convert from ciphertext to point");
return point;
}
EC_POINT *
ECJoin::randomPoint() {
EC_POINT * point = my_EC_POINT_new(group);
BIGNUM *x = my_BN_new(), *y = my_BN_new(), * rem = my_BN_new();
bool found = false;
while (!found) {
BN_rand_range(x, order);
if (EC_POINT_set_compressed_coordinates_GFp(group, point, x, 1, bn_ctx)) {
throw_c(EC_POINT_get_affine_coordinates_GFp(group, point, x, y, bn_ctx),"issue getting coordinates");
if(BN_is_zero(x) || BN_is_zero(y)) {
found = false;
continue;
}
if (EC_POINT_is_on_curve(group, point, bn_ctx)) {
LOG(crypto) << "found correct random point, P";
found = true;
} else {
LOG(crypto) << "P not on curve; try again";
}
} else {
LOG(crypto) << "P is bad random point; try again";
}
}
BN_free(x);
BN_free(y);
BN_free(rem);
return point;
}
ECJoin::ECJoin()
{
group = EC_GROUP_new_by_curve_name(NID);
throw_c(group, "issue creating new curve");
bn_ctx = BN_CTX_new();
throw_c(bn_ctx, "failed to create big number context");
order = my_BN_new();
throw_c(EC_GROUP_get_order(group, order, bn_ctx), "failed to retrieve the order");
Infty = my_EC_POINT_new(group);
throw_c(EC_POINT_set_to_infinity(group, Infty), "could not create point at infinity");
P = randomPoint();
ZeroBN = BN_new();
throw_c(ZeroBN != NULL, "cannot create big num");
BN_zero(ZeroBN);
}
static EC_POINT *
mul(const EC_GROUP * group, const BIGNUM * ZeroBN, const EC_POINT * Point, const BIGNUM * Scalar, BN_CTX * bn_ctx) {
EC_POINT * ans = EC_POINT_new(group);
throw_c(ans, "cannot create point ");
//ans = sk->kp * cbn
throw_c(EC_POINT_mul(group, ans, ZeroBN, Point, Scalar, bn_ctx), "issue when multiplying ec");
return ans;
}
static BIGNUM *
my_BN_bin2bn(string data) {
BIGNUM * res = BN_bin2bn((unsigned char *) data.data(), (int) data.length(), NULL);
throw_c(res, "could not convert from binary to BIGNUM ");
return res;
}
ECJoinSK *
ECJoin::getSKey(const AES_KEY * baseKey, const string & columnKey) {
ECJoinSK * skey = new ECJoinSK();
skey->aesKey = baseKey;
BIGNUM * bnkey = my_BN_bin2bn(columnKey);
skey->k = my_BN_mod(bnkey, order, bn_ctx);
skey->kP = mul(group, ZeroBN, P, skey->k, bn_ctx);
BN_free(bnkey);
return skey;
}
ECDeltaSK *
ECJoin::getDeltaKey(const ECJoinSK * key1, const ECJoinSK * key2) {
ECDeltaSK * delta = new ECDeltaSK();
delta->group = group;
delta->ZeroBN = ZeroBN;
BIGNUM * key1Inverse = BN_mod_inverse(NULL, key1->k, order, bn_ctx);
throw_c(key1Inverse, "could not compute inverse of key 1");
delta->deltaK = BN_new();
BN_mod_mul(delta->deltaK, key1Inverse, key2->k, order, bn_ctx);
throw_c(delta->deltaK, "failed to multiply");
BN_free(key1Inverse);
return delta;
}
// a PRF with 128 bits security, but 160 bit output
string
ECJoin::PRFForEC(const AES_KEY * sk, const string & ptext) {
string nptext = ptext;
unsigned int len = (uint) ptext.length();
if (bytesLong > len) {
for (unsigned int i = 0 ; i < bytesLong - len; i++) {
nptext = nptext + "0";
}
}
// should collapse down to 1 AES_BLOCK_SIZE using SHA1
return encrypt_AES(nptext, sk, 1).substr(0, bytesLong);
}
string
ECJoin::point2Str(const EC_GROUP * group, const EC_POINT * point) {
unsigned char buf[ECJoin::MAX_BUF+1];
memset(buf, 0, ECJoin::MAX_BUF);
size_t len = 0;
len = EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED, buf, MAX_BUF, NULL);
throw_c(len, "cannot serialize EC_POINT ");
return string((char *)buf, len);
}
string
ECJoin::encrypt(const ECJoinSK * sk, const string & ptext) {
// CONVERT ptext in PRF(ptext)
string ctext = PRFForEC(sk->aesKey, ptext);
//cbn = PRF(ptext)
BIGNUM * cbn = my_BN_bin2bn(ctext);
BIGNUM * cbn2 = my_BN_mod(cbn, order, bn_ctx);
//ans = sk->kp * cbn
EC_POINT * ans = mul(group, ZeroBN, sk->kP, cbn2, bn_ctx);
string res = point2Str(group, ans);
EC_POINT_free(ans);
BN_free(cbn);
BN_free(cbn2);
return res;
}
string
ECJoin::adjust(const ECDeltaSK * delta, const string & ctext) {
EC_POINT * point = str2Point(delta->group, ctext);
EC_POINT * res = mul(delta->group, delta->ZeroBN, point, delta->deltaK, NULL);
string result = point2Str(delta->group, res);
EC_POINT_free(res);
EC_POINT_free(point);
return result;
}
ECJoin::~ECJoin()
{
BN_free(order);
EC_POINT_free(P);
EC_GROUP_clear_free(group);
BN_CTX_free(bn_ctx);
}
/*** some internal test code ..
cerr << "is key null? " << pretty_bn2str(key1->k) << "\n";
cerr << "comp key oder " << BN_cmp(key1->k, order) << "\n";
BIGNUM * key1Inverse = BN_mod_inverse(NULL, key1->k, order, bn_ctx);
throw_c(key1Inverse, "could not compute inverse of key 1");
delta->deltaK = BN_new();
BN_mod_mul(delta->deltaK, key1Inverse, key2->k, order, bn_ctx);
throw_c(delta->deltaK, "failed to multiply");
//delta * k1 = k2?
cerr << "(remove this code) \n checking delta \n";
BIGNUM * temp = BN_new();
BN_mod_mul(temp, delta->deltaK, key1->k, order, bn_ctx);
cerr << "cmp temp key2 " << BN_cmp(temp, key2->k) << "\n";
BN_free(temp);
//let's now check that key1->kP * deltaK = key2->Kp
cerr << "remove code here\n";
cerr << "are the two points equal? " << EC_POINT_cmp(group, mul(group, ZeroBN, key1->kP, delta->deltaK, bn_ctx), key2->kP, bn_ctx) << "\n";
//let's now check with the ciphertexts
cerr << "are the points with ciph equal? " << EC_POINT_cmp(group,
mul(group, ZeroBN, str2Point(group, c1), delta->deltaK, bn_ctx),
str2Point(group, c2),
bn_ctx) << "\n";
*/
/* static string
pretty_bn2str(BIGNUM * bn) {
unsigned char * tov = new unsigned char[256];
int len = BN_bn2bin(bn, tov);
throw_c(len, "cannot convert from bn to binary ");
string res = "";
for (int i = 0 ; i < len ; i++) {
res = res + StringFromVal(tov[i]) + " ";
}
return res;
}
*/
#pragma once
/*
* ECJoin.h
*
* Implements CryptDB's adjustable join encryption scheme.
* It is based on the elliptic-curve DDH assumption.
*
* Currently, it is using the NIST curve denoted NID_X9_62_prime192v1 believed to satisfy ECDDH
* To use a different NIST curve, simply modify the NID field below.
*
*
* Public parameters:
* G: elliptic curve group of prime order
* P: a random point on the elliptic curve
* order: the order of G
*
* To encrypt v, we compute E_k[v] := PRF_k(v) * k * P \in G, where
* k: secret key
*
* To adjust encryption of v under k1, to encryption under k2, we perform:
* \delta k = k2 * k1^{-1} mod order
* E_k2[v] = E_k1[v]*\delta k \in G
*
* TODO: may speed up by:
* - passing BN_CTX * to some functions (and CTX for point, group, if any)
* - using ssl's preprocessing functions
* - use NIST curves with less bits representation, e.g., NID_secp160r1; there are even shorter
*/
#include <openssl/obj_mac.h>
#include <openssl/bn.h>
#include <openssl/ec.h>
#include <crypto/BasicCrypto.hh>
struct ECJoinSK{
const AES_KEY * aesKey;
BIGNUM * k; //secret key
EC_POINT * kP;
};
struct ECDeltaSK {
BIGNUM * deltaK;
EC_GROUP * group;
BIGNUM * ZeroBN;
};
class ECJoin
{
public:
//setups the elliptic curve and systems parameters
ECJoin();
ECJoinSK * getSKey(const AES_KEY * baseKey, const std::string & columnKey);
//returns secret key needed to adjust from encryption with key 1 to encryption with key 2
ECDeltaSK * getDeltaKey(const ECJoinSK * key1, const ECJoinSK * key2);
std::string encrypt(const ECJoinSK * sk, const std::string & ptext);
static std::string adjust(const ECDeltaSK * deltaSK, const std::string & ctext);
virtual
~ECJoin();
private:
//setup parameters
EC_GROUP * group;
EC_POINT * P;
//helper parameters
BIGNUM * order; //order of the group
EC_POINT * Infty;
BIGNUM * ZeroBN;
BN_CTX * bn_ctx;
//using curve of 160 bits prime field \n";
static const int NID = NID_X9_62_prime192v1;
static const unsigned int bytesLong = 24;
static const unsigned int MAX_BUF = 256;
/*** Helper Functions ***/
//returns a random point on the EC
EC_POINT * randomPoint();
// a PRF with 128 bits security, but bytesLong output
static std::string PRFForEC(const AES_KEY * sk, const std::string & ptext);
static std::string point2Str(const EC_GROUP * group, const EC_POINT * point);
};
OBJDIRS += crypto
CRYPTOSRC := BasicCrypto.cc paillier.cc urandom.cc arc4.cc hgd.cc pbkdf2.cc \
ecjoin.cc ECJoin.cc search.cc skip32.cc ffx.cc online_ope.cc mont.cc \
prng.cc ope.cc SWPSearch.cc
CRYPTOOBJ := $(patsubst %.cc,$(OBJDIR)/crypto/%.o,$(CRYPTOSRC))
all: $(OBJDIR)/libedbcrypto.a $(OBJDIR)/libedbcrypto.so
$(OBJDIR)/libedbcrypto.so: $(CRYPTOOBJ) $(OBJDIR)/libedbutil.so
$(CXX) -shared -o $@ $(CRYPTOOBJ) $(LDFLAGS) $(LDRPATH) \
-ledbutil -lcrypto -lntl
$(OBJDIR)/libedbcrypto.a: $(CRYPTOOBJ)
$(AR) r $@ $(CRYPTOOBJ)
#all: $(OBJDIR)/crypto/x
$(OBJDIR)/crypto/x: $(OBJDIR)/crypto/x.o $(OBJDIR)/libedbcrypto.so
$(CXX) $< -o $@ $(LDFLAGS) $(LDRPATH) -ledbcrypto
install: install_crypto
.PHONY: install_crypto
install_crypto: $(OBJDIR)/libedbcrypto.so
install -m 644 $(OBJDIR)/libedbcrypto.so /usr/lib
# vim: set noexpandtab:
/*
* Crypto.cpp
*
*
* Author: raluca
*/
#include <iostream>
#include <fstream>
#include <crypto/SWPSearch.hh>
#include <util/util.hh>
using namespace std;
unsigned char fixedIV[] =
{34, 145, 42, 12, 56, 13, 111, 100, 98, 6, 2, 63, 88, 4, 22, 74};
static string iv_det;
static const bool DEBUG = false;
string
SWP::PRP(const string & key, const string & val)
{
return encryptSym(key, val, key);
}
/*************** Sym key crypto ******************/
//pads with 10..00 making length of result be a multiple of len (bytes)
static string
pad(const string & vec, unsigned int len)
{
string result;
unsigned int newlen;
if (vec.length() % len == 0) {
newlen = vec.length() + len;
} else {
newlen = (vec.length() / len + 1) * len;
}
result = vec;
result.resize(newlen);
result[vec.length()] = 1;
for (unsigned int i = vec.length()+1; i < result.length(); i++) {
result[i] = 0;
}
return result;
}
static string
unpad(const string & vec)
{
int index = vec.length() - 1;
while ((index > 0) && (vec[index] == 0)) {
index--;
}
throw_c((index>=0) && (vec[index] == 1),
"input was not padded correctly");
return vec.substr(0, index);
}
string
SWP::encryptSym(const string & key, const string & val, const string & iv)
{
throw_c(key.length() == AES_BLOCK_SIZE, "key has incorrect length");
throw_c(iv.length() == AES_BLOCK_SIZE, "iv has incorrect length");
AES_KEY aes_key;
AES_set_encrypt_key((const unsigned char *)key.c_str(), AES_BLOCK_BITS, &aes_key);
string val2 = pad(val, AES_BLOCK_SIZE);
unsigned int newlen = val2.length();
auto result = vector<unsigned char>(newlen);
unsigned char * newiv = new unsigned char[iv.length()];
memcpy(newiv, iv.c_str(), iv.length());
AES_cbc_encrypt((const unsigned char *)val2.c_str(), &result[0], newlen, &aes_key,
newiv, AES_ENCRYPT);
return string((char*)&result[0], newlen);
}
string
SWP::decryptSym(const string & key, const string & ciph, const string & iv)
{
throw_c(iv.length() == AES_BLOCK_SIZE, "iv has incorrect length");
throw_c(key.length() == AES_BLOCK_SIZE, "key has incorrect length");
AES_KEY aes_key;
AES_set_decrypt_key((const unsigned char *)key.c_str(), AES_BLOCK_BITS, &aes_key);
unsigned int ciphlen = ciph.length();
auto result = new unsigned char[ciphlen];
unsigned char * newiv = new unsigned char[iv.length()];
memcpy(newiv, iv.c_str(), iv.length());
AES_cbc_encrypt((const unsigned char*)ciph.c_str(), result, ciphlen, &aes_key,
newiv, AES_DECRYPT);
return unpad(string((const char *)result, ciphlen));
}
string
SWP::encryptSym(const string & key, const string & val)
{
string salt = random(SWP_SALT_LEN);
string iv = PRP(key, salt);
string ciph = encryptSym(key, val, iv);
return salt+ciph;
}
string
SWP::decryptSym(const string & key, const string & ciph)
{
string salt = ciph.substr(0, SWP_SALT_LEN);
string iv = PRP(key, salt);
string ciph2 = ciph.substr(SWP_SALT_LEN, ciph.length() - SWP_SALT_LEN);
return decryptSym(key, ciph2, iv);
}
string
SWP::random(unsigned int nobytes)
{
unsigned char * bin = new unsigned char[nobytes];
RAND_bytes(bin, nobytes);
return string((const char *)bin, nobytes);
}
/**************************** SWP ****************/
// this function performs half of the encrypt job up to the point at which
// tokens are generated
void
SWP::SWPHalfEncrypt(const string & key, string word, string & ciph,
string & wordKey)
{
//encryption of word E[W_i]
string IV((const char *)fixedIV, AES_BLOCK_SIZE);
ciph = encryptSym(key, word, IV);
//L_i and R_i
string L_i;
if (SWP::canDecrypt) {
L_i = ciph.substr(0, SWPr);
}
//wordKey: k_i = PRP_{key}(E[W_i])
if (!SWP::canDecrypt) {
wordKey = PRP(key, ciph);
} else {
wordKey = PRP(key, L_i);
}
}
static string
bytewise_xor(const string & a, const string & b) {
throw_c(a.length() == b.length(), "bytewise_xor expects equal lengths");
unsigned int len = a.length();
char * res = new char[len];
for (unsigned int i = 0; i < len; i++) {
res[i] = a[i] xor b[i];
}
return string(res, len);
}
string
SWP::SWPencrypt(const string & key, string word, unsigned int index)
{
if (DEBUG) {cerr << "encrypting " << word << "\n "; }
string ciph, wordKey;
SWPHalfEncrypt(key, word, ciph, wordKey);
//S_i
string salt;
if (SWP::canDecrypt) {
salt = PRP(key, strFromVal(index));
salt = salt.substr(salt.length() - SWPr, SWPr);
} else {
salt = random(SWPr);
}
//F_{k_i} (S_i)
string func = PRP(wordKey, salt);
if (SWP::canDecrypt) {
func = func.substr(SWPr, SWPm);
}
return bytewise_xor(ciph, salt + func);
}
Token
SWP::token(const string & key, const string & word)
{
Token t = Token();
SWPHalfEncrypt(key, word, t.ciph, t.wordKey);
return t;
}
bool
SWP::SWPsearch(const Token & token, const string & ciph)
{
if (DEBUG) { cerr << "searching! \n"; }
//remove E[W_i]
string ciph2 = bytewise_xor(ciph, token.ciph);
//remains salt, PRP(wordkey, salt)
string salt = ciph2.substr(0, SWPr);
string funcpart = ciph2.substr(SWPr, ciph2.length() - SWPr);
string func = PRP(token.wordKey, salt);
if (SWP::canDecrypt) {
func = func.substr(SWPr, SWPm);
}
if (func == funcpart) {
return true;
}
return false;
}
list<string> *
SWP::encrypt(const string & key, const list<string> & words)
{
list<string> * result = new list<string>();
unsigned int index = 0;
for (list<string>::const_iterator it = words.begin(); it != words.end();
it++) {
index++;
string word = *it;
throw_c(word.length() < SWPCiphSize, string(
" given word ") + word +
" is longer than SWPCiphSize");
result->push_back(SWPencrypt(key, word, index));
}
return result;
}
string
SWP::SWPdecrypt(const string & key, const string & word, unsigned int index)
{
//S_i
string salt = PRP(key, strFromVal(index));
salt = salt.substr(salt.length() - SWPr, SWPr);
//L_i
string L_i = bytewise_xor(salt, word.substr(0, SWPr));
//k_i
string wordKey = PRP(key, L_i);
//F_{k_i} (S_i)
string func = PRP(wordKey, salt).substr(SWPr, SWPm);
string R_i = bytewise_xor(func, word.substr(SWPr, SWPm));
return decryptSym(key, L_i + R_i, string((const char *)fixedIV, AES_BLOCK_SIZE));
}
list<string> *
SWP::decrypt(const string & key, const list<string> & ciph)
{
list<string> * result = new list<string>();
throw_c(
canDecrypt,
"the current choice of parameters for SWP does not allow decryption");
unsigned int index = 0;
for (list<string>::const_iterator it = ciph.begin(); it != ciph.end();
it++) {
index++;
string word = *it;
throw_c(word.length() == SWPCiphSize,
" given ciphertext with invalid length ");
result->push_back(SWPdecrypt(key, word, index));
}
return result;
}
list<unsigned int> *
SWP::search(const Token & token, const list<string> & ciphs)
{
list<unsigned int> * res = new list<unsigned int>();
unsigned int index = 0;
for (list<string>::const_iterator cit = ciphs.begin(); cit != ciphs.end();
cit++) {
if (SWPsearch(token, *cit)) {
res->push_back(index);
}
index++;
}
return res;
}
bool
SWP::searchExists(const Token & token, const list<string> & ciphs)
{
for (list<string>::const_iterator cit = ciphs.begin(); cit != ciphs.end();
cit++) {
if (SWPsearch(token, *cit)) {
return true;
}
}
return false;
}
#pragma once
/*
* Crypto.h
*
*
* Author: raluca
*
* Implementation of the Song-Wagner-Perrig cryptosystem, 2000
*
* TODO: interpret "%" in searches
* TODO: because of the way we use their protocol, we can simplify their encryption scheme by
* -- (implemented) no need for Si = PRP_k(i), any random Si is enough (in cases where we do not care of decryption)
* -- the ciphertext can be made shorter as long as it does not cause a collision
* -- Si and F_ki(Si) being the same for the same word, and Si matching Fki(Si) for an incorrect search matching (false positive in search)
* or SWPCiphertext size making different words encrypted to match to the same deterministic encryption E[W]
* -- suggestion: Si and F each 32bits
* -- removind a layer of PRP/encryption given by the counter
*/
#include <openssl/aes.h>
#include <openssl/rand.h>
#include <list>
// for all following constants unit is bytes
const unsigned int SWPCiphSize = 16; // must be <= 16
const unsigned int SWPm = 4; //the rate of false positives when searching is
// 1/2^{m*8}
const unsigned int SWP_SALT_LEN = 8; //the size of salt in bytes
const unsigned int SWPr = SWPCiphSize - SWPm;
typedef struct Token {
std::string ciph;
std::string wordKey;
} Token;
class SWP {
public:
/*
* Encrypts the list of words with key.
*
* Requires: each word < SWPCiphSize.
*
* Returns: NULL on problem.
*/
static std::list<std::string> * encrypt(const std::string & key,
const std::list<std::string> & words);
/*
* Decrypts each word in the list ciphs.
*
* Decryption only works and should be called if SWPCiphSize is multiple
* of AES_BLOCK_BITS (see canDecrypt flag)
*
*/
static std::list<std::string> * decrypt(const std::string & key,
const std::list<std::string> & ciphs);
/*
* Given the secret key and the word to search for, returns the token to
* be used during searching.
*/
static Token token(const std::string & key, const std::string & word);
/*
* Returns a list of indexes of words in the list of ciphertexts ciphs
* that match the token based on SWP or a boolean indicating whether
* the value exists in the given ciphertexts or not.
*/
static std::list<unsigned int> * search(const Token & token,
const std::list<std::string> & ciphs);
static bool searchExists(const Token & token, const std::list<std::string> & ciphs);
static const bool canDecrypt = (SWPCiphSize % AES_BLOCK_SIZE == 0);
/** PRP **/
// Computes PRP_{key}(val), where PRP is a pseudorandom permutation
// Result is empty on problem
static std::string PRP(const std::string & key, const std::string & val);
private:
/* Symmetric key crypto -- AES
* requires: iv of AES_BLOCK_BYTES */
static std::string encryptSym(const std::string & key, const std::string & val,
const std::string & iv);
static std::string decryptSym(const std::string & key, const std::string & ciph,
const std::string & iv);
/*
* AES semantic (probabilistic) secure encryption
* some salt is chosen randomly and appended to the ciphertext
*/
static std::string encryptSym(const std::string & key, const std::string & val);
static std::string decryptSym(const std::string & key, const std::string & ciph);
//returns a random binary that has nobytes, chosen at random
static std::string random(unsigned int nobytes);
/*
* SWP helper functions
*/
static std::string SWPencrypt(const std::string & key, std::string word,
unsigned int index);
static std::string SWPdecrypt(const std::string & key, const std::string & word,
unsigned int index);
static bool SWPsearch(const Token & token, const std::string & ciph);
static void SWPHalfEncrypt(const std::string & key, std::string word, std::string & ciph,
std::string & wordKey);
};
#pragma once
#include <stdint.h>
#include <openssl/aes.h>
#include <string>
#include <cstring>
#include <util/errstream.hh>
class AES {
public:
AES(const std::string &key) {
throw_c(key.size() == 16 || key.size() == 24 || key.size() == 32);
AES_set_encrypt_key((const uint8_t*) key.data(), key.size() * 8, &enc);
AES_set_decrypt_key((const uint8_t*) key.data(), key.size() * 8, &dec);
}
void block_encrypt(const void *ptext, void *ctext) const {
AES_encrypt((const uint8_t*) ptext, (uint8_t*) ctext, &enc);
}
void block_decrypt(const void *ctext, void *ptext) const {
AES_decrypt((const uint8_t*) ctext, (uint8_t*) ptext, &dec);
}
static const size_t blocksize = 16;
private:
AES_KEY enc;
AES_KEY dec;
};
#include <crypto/arc4.hh>
using namespace std;
arc4::arc4(const std::string &key)
{
reset();
for (size_t n = 0; n < key.size(); n += 128)
addkey((const uint8_t *) &key[n], min((size_t) 128, key.size() - n));
j = i;
/* discard first bytes */
for (int n = 0; n < 4096; n++)
getbyte();
}
void
arc4::reset()
{
i = 0xff;
j = 0;
for (int n = 0; n < 0x100; n++)
s[n] = n;
}
void
arc4::addkey(const uint8_t *key, size_t keylen)
{
size_t n, keypos;
uint8_t si;
for (n = 0, keypos = 0; n < 256; n++, keypos++) {
if (keypos >= keylen)
keypos = 0;
i = (i + 1) & 0xff;
si = s[i];
j = (j + si + key[keypos]) & 0xff;
s[i] = s[j];
s[j] = si;
}
}
uint8_t
arc4::getbyte()
{
uint8_t si, sj;
i = (i + 1) & 0xff;
si = s[i];
j = (j + si) & 0xff;
sj = s[j];
s[i] = sj;
s[j] = si;
return s[(si + sj) & 0xff];
}
#pragma once
#include <string>
class arc4 {
public:
arc4(const std::string &key);
uint8_t getbyte();
private:
arc4(const arc4 &);
void reset();
void addkey(const uint8_t *key, size_t keylen);
uint8_t i;
uint8_t j;
uint8_t s[256];
};
#pragma once
#include <vector>
#include <stdint.h>
#include <openssl/blowfish.h>
class blowfish {
public:
blowfish(const std::string &key) {
BF_set_key(&k, key.size(), (const uint8_t*) key.data());
}
void block_encrypt(const void *ptext, void *ctext) const {
BF_ecb_encrypt((const uint8_t*) ptext, (uint8_t*) ctext, &k, BF_ENCRYPT);
}
void block_decrypt(const void *ctext, void *ptext) const {
BF_ecb_encrypt((const uint8_t*) ctext, (uint8_t*) ptext, &k, BF_DECRYPT);
}
uint64_t encrypt(uint64_t pt) const {
uint64_t ct;
block_encrypt(&pt, &ct);
return ct;
}
uint64_t decrypt(uint64_t ct) const {
uint64_t pt;
block_decrypt(&ct, &pt);
return pt;
}
static const size_t blocksize = 8;
private:
BF_KEY k;
};
#pragma once
#include <stdexcept>
#include <ostream>
#include <openssl/bn.h>
#include <openssl/crypto.h>
#include <util/errstream.hh>
class _bignum_ctx {
public:
_bignum_ctx() { c = BN_CTX_new(); }
~_bignum_ctx() { BN_CTX_free(c); }
BN_CTX *ctx() { return c; }
static BN_CTX *the_ctx() {
static _bignum_ctx cx;
return cx.ctx();
}
private:
BN_CTX *c;
};
class bignum {
public:
bignum() {
BN_init(&b);
}
bignum(unsigned long v) {
BN_init(&b);
BN_set_word(&b, v);
}
bignum(const bignum &other) {
BN_init(&b);
throw_c(BN_copy(&b, other.bn()));
}
bignum(const uint8_t *buf, size_t nbytes) {
BN_init(&b);
throw_c(BN_bin2bn(buf, nbytes, &b));
}
bignum(const std::string &v) {
BN_init(&b);
throw_c(BN_bin2bn((uint8_t*) v.data(), v.size(), &b));
}
~bignum() { BN_free(&b); }
BIGNUM *bn() { return &b; }
const BIGNUM *bn() const { return &b; }
unsigned long word() const {
unsigned long v = BN_get_word(&b);
if (v == 0xffffffffL)
throw std::runtime_error("out of range");
return v;
}
#define op(opname, func, args...) \
bignum opname(const bignum &mod) { \
bignum res; \
throw_c(1 == func(res.bn(), &b, mod.bn(), ##args)); \
return res; \
}
op(operator+, BN_add)
op(operator-, BN_sub)
op(operator%, BN_mod, _bignum_ctx::the_ctx())
op(operator*, BN_mul, _bignum_ctx::the_ctx())
#undef op
#define pred(predname, cmp) \
bool predname(const bignum &other) { \
return BN_cmp(&b, other.bn()) cmp; \
}
pred(operator<, < 0)
pred(operator<=, <= 0)
pred(operator>, > 0)
pred(operator>=, >= 0)
pred(operator==, == 0)
#undef pred
bignum invmod(const bignum &mod) {
bignum r;
throw_c(BN_mod_inverse(r.bn(), &b, mod.bn(), _bignum_ctx::the_ctx()));
return r;
}
private:
BIGNUM b;
};
static inline std::ostream&
operator<<(std::ostream &out, const bignum &bn)
{
char *s = BN_bn2dec(bn.bn());
out << s;
OPENSSL_free(s);
return out;
}
#pragma once
#include <vector>
#include <stdint.h>
#include <string.h>
template<class BlockCipher>
void
xor_block(void *dstv, const void *av, const void *bv)
{
uint8_t *dst = (uint8_t*) dstv;
const uint8_t *a = (const uint8_t*) av;
const uint8_t *b = (const uint8_t*) bv;
for (size_t j = 0; j < BlockCipher::blocksize; j++)
dst[j] = a[j] ^ b[j];
}
template<class BlockCipher>
void
cbc_encrypt(const BlockCipher *c,
const std::string &ivec,
const std::string &ptext,
std::string *ctext)
{
throw_c(ivec.size() == BlockCipher::blocksize);
size_t ptsize = ptext.size();
throw_c(ptsize >= BlockCipher::blocksize);
ctext->resize(ptsize);
const uint8_t *iv = (const uint8_t*) ivec.data();
const uint8_t *pt = (const uint8_t*) ptext.data();
uint8_t *ct = (uint8_t*) ctext->data();
for (size_t i = 0;
i <= ptsize - BlockCipher::blocksize;
i += BlockCipher::blocksize)
{
uint8_t x[BlockCipher::blocksize];
const uint8_t *y = (i == 0) ? &iv[0] : &ct[i-BlockCipher::blocksize];
xor_block<BlockCipher>(x, &pt[i], y);
c->block_encrypt(x, &ct[i]);
}
// Ciphertext stealing (CTS)
size_t leftover = ptsize % BlockCipher::blocksize;
if (leftover) {
uint8_t x[BlockCipher::blocksize];
const uint8_t *y = &ct[ptsize-leftover-BlockCipher::blocksize];
uint8_t z[BlockCipher::blocksize];
memset(z, 0, BlockCipher::blocksize);
memcpy(z, &pt[ptsize-leftover], leftover);
xor_block<BlockCipher>(x, z, y);
memcpy(&ct[ptsize-leftover], &ct[ptsize-leftover-BlockCipher::blocksize], leftover);
c->block_encrypt(x, &ct[ptsize-leftover-BlockCipher::blocksize]);
}
}
template<class BlockCipher>
void
cbc_decrypt(const BlockCipher *c,
const std::string &ivec,
const std::string &ctext,
std::string *ptext)
{
throw_c(ivec.size() == BlockCipher::blocksize);
size_t ctsize = ctext.size();
throw_c(ctsize >= BlockCipher::blocksize);
ptext->resize(ctsize);
const uint8_t *iv = (const uint8_t*) ivec.data();
const uint8_t *ct = (const uint8_t*) ctext.data();
uint8_t *pt = (uint8_t*) ptext->data();
for (size_t i = 0;
i <= ctsize - BlockCipher::blocksize;
i += BlockCipher::blocksize)
{
uint8_t x[BlockCipher::blocksize];
c->block_decrypt(&ct[i], x);
const uint8_t *y = (i == 0) ? &iv[0] : &ct[i-BlockCipher::blocksize];
xor_block<BlockCipher>(&pt[i], x, y);
}
// Ciphertext stealing (CTS)
size_t leftover = ctsize % BlockCipher::blocksize;
if (leftover) {
uint8_t xlast[BlockCipher::blocksize];
c->block_decrypt(&ct[ctsize-leftover-BlockCipher::blocksize], xlast);
uint8_t ctprev[BlockCipher::blocksize];
memcpy(&ctprev[0], &ct[ctsize-leftover], leftover);
memcpy(&ctprev[leftover], &xlast[leftover], BlockCipher::blocksize-leftover);
uint8_t ptlast[BlockCipher::blocksize];
xor_block<BlockCipher>(ptlast, xlast, ctprev);
memcpy(&pt[ctsize-leftover], ptlast, leftover);
uint8_t xprev[BlockCipher::blocksize];
c->block_decrypt(ctprev, xprev);
const uint8_t *y = (ctsize < 2*BlockCipher::blocksize) ?
&iv[0] :
&ct[ctsize-leftover-2*BlockCipher::blocksize];
xor_block<BlockCipher>(&pt[ctsize-leftover-BlockCipher::blocksize],
xprev, y);
}
}
#pragma once
#include <vector>
#include <stdint.h>
template<class BlockCipher>
class cbcmac {
public:
cbcmac(const BlockCipher *cx) {
c = cx;
memset(v, 0, BlockCipher::blocksize);
mbytes = 0;
}
cbcmac(const BlockCipher *cx, void *iv) {
c = cx;
memcpy(v, iv, BlockCipher::blocksize);
mbytes = 0;
}
void update(const void *data, size_t len) {
const uint8_t *d = static_cast<const uint8_t *> (data);
if (mbytes) {
size_t ncopy = std::min(len, BlockCipher::blocksize - mbytes);
memcpy(&m[mbytes], d, ncopy);
d += ncopy;
len -= ncopy;
mbytes += ncopy;
}
if (mbytes == BlockCipher::blocksize) {
do_block(m);
mbytes = 0;
}
while (len >= BlockCipher::blocksize) {
do_block(d);
d += BlockCipher::blocksize;
len -= BlockCipher::blocksize;
}
if (len) {
memcpy(m, d, len);
mbytes = len;
}
}
void update(const std::string &v) {
update(v.data(), v.size());
}
void final(uint8_t *buf) {
if (mbytes) {
memset(&m[mbytes], 0, BlockCipher::blocksize - mbytes);
do_block(m);
}
memcpy(buf, v, BlockCipher::blocksize);
}
std::string final() {
std::string f;
f.resize(BlockCipher::blocksize);
final((uint8_t*) f.data());
return f;
}
static const size_t blocksize = BlockCipher::blocksize;
private:
void do_block(const uint8_t *p) {
uint8_t x[BlockCipher::blocksize];
for (size_t i = 0; i < BlockCipher::blocksize; i++)
x[i] = v[i] ^ p[i];
c->block_encrypt(x, v);
}
uint8_t v[BlockCipher::blocksize];
uint8_t m[BlockCipher::blocksize];
uint8_t mbytes;
const BlockCipher *c;
};
#pragma once
#include <string>
#include <cstring>
#include <crypto/cbc.hh>
template<class BlockCipher>
void
cmc_encrypt(const BlockCipher *c,
const std::string &ptext,
std::string *ctext)
{
throw_c(ptext.size() % BlockCipher::blocksize == 0);
ctext->resize(ptext.size());
uint8_t x[BlockCipher::blocksize];
memset(x, 0, BlockCipher::blocksize);
for (size_t i = 0; i < ptext.size(); i += BlockCipher::blocksize) {
uint8_t y[BlockCipher::blocksize];
xor_block<BlockCipher>(y, &ptext[i], x);
c->block_encrypt(y, &(*ctext)[i]);
memcpy(x, &(*ctext)[i], BlockCipher::blocksize);
}
uint8_t m[BlockCipher::blocksize];
uint8_t carry = 0;
for (size_t j = BlockCipher::blocksize; j != 0; j--) {
uint16_t a = (*ctext)[j - 1] ^
(*ctext)[j - 1 + ptext.size() - BlockCipher::blocksize];
m[j - 1] = carry | (uint8_t) (a << 1);
carry = a >> 7;
}
m[BlockCipher::blocksize-1] |= carry;
for (size_t i = 0; i < ptext.size(); i += BlockCipher::blocksize)
for (size_t j = 0; j < BlockCipher::blocksize; j++)
(*ctext)[i+j] ^= m[j];
memset(x, 0, BlockCipher::blocksize);
for (size_t i = ptext.size(); i != 0; i -= BlockCipher::blocksize) {
uint8_t y[BlockCipher::blocksize];
c->block_encrypt(&(*ctext)[i - BlockCipher::blocksize], y);
uint8_t z[BlockCipher::blocksize];
xor_block<BlockCipher>(z, y, x);
memcpy(x, &(*ctext)[i - BlockCipher::blocksize], BlockCipher::blocksize);
memcpy(&(*ctext)[i - BlockCipher::blocksize], z, BlockCipher::blocksize);
}
}
template<class BlockCipher>
void
cmc_decrypt(const BlockCipher *c,
const std::string &ctext,
std::string *ptext)
{
throw_c(ctext.size() % BlockCipher::blocksize == 0);
ptext->resize(ctext.size());
uint8_t x[BlockCipher::blocksize];
memset(x, 0, BlockCipher::blocksize);
for (size_t i = ctext.size(); i != 0; i -= BlockCipher::blocksize) {
uint8_t y[BlockCipher::blocksize];
xor_block<BlockCipher>(y, &ctext[i-BlockCipher::blocksize], x);
c->block_decrypt(y, &(*ptext)[i - BlockCipher::blocksize]);
memcpy(x, &(*ptext)[i - BlockCipher::blocksize], BlockCipher::blocksize);
}
uint8_t m[BlockCipher::blocksize];
uint8_t carry = 0;
for (size_t j = BlockCipher::blocksize; j != 0; j--) {
uint16_t a = (*ptext)[j - 1] ^
(*ptext)[j - 1 + ctext.size() - BlockCipher::blocksize];
m[j - 1] = carry | (uint8_t) (a << 1);
carry = a >> 7;
}
m[BlockCipher::blocksize-1] |= carry;
for (size_t i = 0; i < ctext.size(); i += BlockCipher::blocksize) {
for (size_t j = 0; j < BlockCipher::blocksize; j++)
(*ptext)[i+j] ^= m[j];
}
memset(x, 0, BlockCipher::blocksize);
for (size_t i = 0; i < ctext.size(); i += BlockCipher::blocksize) {
uint8_t y[BlockCipher::blocksize];
c->block_decrypt(&(*ptext)[i], y);
uint8_t z[BlockCipher::blocksize];
xor_block<BlockCipher>(z, y, x);
memcpy(x, &(*ptext)[i], BlockCipher::blocksize);
memcpy(&(*ptext)[i], z, BlockCipher::blocksize);
}
}
/*
* Damgard-Jurik (a generalization of Paillier) provides a ciphertext
* size that is asymptotically close to the plaintext size, rather
* than a factor of 2 larger in standard Paillier.
*
* This may be especially useful in applications where ciphertext space
* is the bottleneck, where in combination with packing, this should
* provide almost no ciphertext storage overheads (except for spacing
* for aggregate overflow).
*
* "A Generalisation, a Simplification and some Applications of
* Paillier's Probabilistic Public-Key System", by Damgard and Jurik.
* <http://www.daimi.au.dk/~ivan/papers/GeneralPaillier.ps>
*/
#pragma once
#include <ostream>
#include <openssl/ec.h>
#include <openssl/bn.h>
class ec_point {
public:
ec_point(const EC_GROUP *group) {
gr = group;
pt = EC_POINT_new(gr);
}
ec_point(const ec_point &other) {
gr = other.gr;
pt = EC_POINT_dup(other.pt, gr);
}
~ec_point() {
EC_POINT_free(pt);
}
ec_point operator*(const bignum &n) const {
bignum zero(0);
ec_point res(gr);
throw_c(EC_POINT_mul(gr, res.p(), zero.bn(),
pt, n.bn(), _bignum_ctx::the_ctx()));
return res;
}
bool operator==(const ec_point &other) const {
return EC_POINT_cmp(gr, pt, other.pt, _bignum_ctx::the_ctx()) == 0;
}
bool operator!=(const ec_point &other) const {
return EC_POINT_cmp(gr, pt, other.pt, _bignum_ctx::the_ctx()) != 0;
}
std::string to_string(point_conversion_form_t form =
POINT_CONVERSION_UNCOMPRESSED) const {
char *s = EC_POINT_point2hex(gr, pt, form, _bignum_ctx::the_ctx());
std::string r(s);
free(s);
return r;
}
EC_POINT *p() { return pt; }
private:
EC_POINT *pt;
const EC_GROUP *gr;
};
static inline std::ostream&
operator<<(std::ostream &out, const ec_point &p)
{
return out << p.to_string();
}
#include <crypto/ecjoin.hh>
#include <crypto/sha.hh>
#include <crypto/prng.hh>
#include <crypto/arc4.hh>
ecjoin::ecjoin(int curve_id)
{
group = EC_GROUP_new_by_curve_name(curve_id);
throw_c(group);
throw_c(EC_GROUP_get_order(group, order.bn(), _bignum_ctx::the_ctx()));
}
ecjoin::~ecjoin()
{
EC_GROUP_free(group);
}
ec_point
ecjoin::adjust(const ec_point &p, const bignum &delta_k)
{
return p * delta_k;
}
ecjoin_priv::ecjoin_priv(const std::string &base_key, int curve_id)
: ecjoin(curve_id), base(sha256::hash(base_key)), basept(group)
{
streamrng<arc4> r(base_key);
for (;;) {
bignum x = r.rand_bn_mod(order);
if (!EC_POINT_set_compressed_coordinates_GFp(group, basept.p(),
x.bn(), 1,
_bignum_ctx::the_ctx()))
continue;
bignum y;
throw_c(EC_POINT_get_affine_coordinates_GFp(group, basept.p(),
x.bn(), y.bn(),
_bignum_ctx::the_ctx()));
if (x == 0 || y == 0)
continue;
if (EC_POINT_is_on_curve(group, basept.p(), _bignum_ctx::the_ctx()))
break;
}
}
ec_point
ecjoin_priv::hash(const std::string &ptext, const std::string &k)
{
auto hash = sha1::hash(ptext);
throw_c(hash.size() >= base.blocksize);
hash.resize(base.blocksize);
std::string enc;
enc.resize(base.blocksize);
base.block_encrypt(&hash[0], &enc[0]);
bignum kn(sha256::hash(k));
bignum enc_bn(enc);
return basept * (kn % order) * (enc_bn % order);
}
bignum
ecjoin_priv::delta(const std::string &k0, const std::string &k1)
{
bignum kn0(sha256::hash(k0));
bignum kn1(sha256::hash(k1));
return ((kn1 % order) * kn0.invmod(order)) % order;
}
#pragma once
#include <openssl/ec.h>
#include <openssl/objects.h>
#include <crypto/aes.hh>
#include <crypto/bn.hh>
#include <crypto/ec.hh>
static int ecjoin_default_curve = NID_X9_62_prime192v1;
class ecjoin {
public:
ecjoin(int curve_id = ecjoin_default_curve);
~ecjoin();
static ec_point adjust(const ec_point &p, const bignum &delta_k);
protected:
EC_GROUP *group;
bignum order;
};
class ecjoin_priv : public ecjoin {
public:
ecjoin_priv(const std::string &base_key,
int curve_id = ecjoin_default_curve);
ec_point hash(const std::string &ptext, const std::string &k);
bignum delta(const std::string &k0, const std::string &k1);
private:
AES base;
ec_point basept;
};
#include <crypto/ffx.hh>
void ffx_mem_to_u64(const uint8_t *p,
uint64_t *a, uint64_t *b,
uint abits, uint bbits)
{
throw_c(abits <= 64 && bbits <= 64);
*a = 0;
*b = 0;
while (abits >= 8) {
*a = *a << 8 | *p;
p++;
abits -= 8;
}
if (abits) {
*a = *a << abits | *p >> (8 - abits);
uint8_t pleft = *p & ((1 << (8 - abits)) - 1);
if (bbits < 8 - abits) {
*b = pleft >> (8 - bbits);
bbits = 0;
} else {
*b = pleft;
bbits -= 8 - abits;
}
p++;
}
while (bbits >= 8) {
*b = *b << 8 | *p;
p++;
bbits -= 8;
}
if (bbits)
*b = *b << bbits | *p >> (8 - bbits);
}
void ffx_u64_to_mem(uint64_t a, uint64_t b,
uint64_t abits, uint64_t bbits,
uint8_t *p)
{
throw_c(abits <= 64 && bbits <= 64);
while (abits >= 8) {
*p = a >> (abits - 8);
p++;
abits -= 8;
}
if (abits) {
*p = a & ((1 << abits) - 1);
if (bbits < 8 - abits) {
*p = (*p << bbits | (b & ((1 << bbits) - 1))) << (8 - abits - bbits);
bbits = 0;
} else {
*p = *p << (8 - abits) | b >> (bbits - (8 - abits));
bbits -= (8 - abits);
}
p++;
}
while (bbits >= 8) {
*p = b >> (bbits - 8);
p++;
bbits -= 8;
}
if (bbits)
*p = b << (8 - bbits);
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#include <NTL/ZZ.h>
#include <crypto/prng.hh>
/*
* KK is the number of elements drawn from an urn where there are NN1 white
* balls and NN2 black balls; the result is the number of white balls in
* the KK sample.
*
* The implementation is based on an adaptation of the H2PEC alg for large
* numbers; see hgd.cc for details
*/
NTL::ZZ HGD(const NTL::ZZ &KK,
const NTL::ZZ &NN1,
const NTL::ZZ &NN2,
PRNG *prng);
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#pragma once
static inline void
pad_blocksize(std::string *ptext, size_t blocksize)
{
size_t plen = ptext->size();
uint8_t pad = blocksize - (plen % blocksize);
ptext->resize(plen + pad);
(*ptext)[plen + pad - 1] = pad;
}
static inline void
unpad_blocksize(std::string *ptext, size_t blocksize)
{
size_t flen = ptext->size();
uint8_t pad = (*ptext)[flen - 1];
ptext->resize(flen - pad);
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment