// create a new open packet packet_t crypt_openize_1a(crypt_t self, crypt_t c, packet_t inner) { unsigned char secret[uECC_BYTES], iv[16], hash[32]; packet_t open; int inner_len; crypt_1a_t cs = (crypt_1a_t)c->cs, scs = (crypt_1a_t)self->cs; open = packet_chain(inner); packet_json(open,&(self->csid),1); inner_len = packet_len(inner); if(!packet_body(open,NULL,4+40+inner_len)) return NULL; // copy in the line public key memcpy(open->body+4, cs->line_public, 40); // get the shared secret to create the iv+key for the open aes if(!uECC_shared_secret(cs->id_public, cs->line_private, secret)) return packet_free(open); crypt_hash(secret,uECC_BYTES,hash); fold1(hash,hash); memset(iv,0,16); iv[15] = 1; // encrypt the inner aes_128_ctr(hash,inner_len,iv,packet_raw(inner),open->body+4+40); // generate secret for hmac if(!uECC_shared_secret(cs->id_public, scs->id_private, secret)) return packet_free(open); hmac_256(secret,uECC_BYTES,open->body+4,40+inner_len,hash); fold3(hash,open->body); return open; }
lob_t ephemeral_encrypt(ephemeral_t ephem, lob_t inner) { lob_t outer; uint8_t iv[16], hmac[32]; size_t inner_len; outer = lob_new(); inner_len = lob_len(inner); if(!lob_body(outer,NULL,16+4+inner_len+4)) return lob_free(outer); // copy in token and create/copy iv memcpy(outer->body,ephem->token,16); memset(iv,0,16); memcpy(iv,&(ephem->seq),4); ephem->seq++; memcpy(outer->body+16,iv,4); // encrypt full inner into the outer aes_128_ctr(ephem->enckey,inner_len,iv,lob_raw(inner),outer->body+16+4); // generate mac key and mac the ciphertext memcpy(hmac,ephem->enckey,16); memcpy(hmac+16,iv,4); hmac_256(hmac,16+4,outer->body+16+4,inner_len,hmac); fold3(hmac,outer->body+16+4+inner_len); return outer; }
lob_t remote_encrypt(remote_t remote, local_t local, lob_t inner) { uint8_t shared[uECC_BYTES+4], iv[16], hash[32], csid = 0x1a; lob_t outer; size_t inner_len; outer = lob_new(); lob_head(outer,&csid,1); inner_len = lob_len(inner); if(!lob_body(outer,NULL,21+4+inner_len+4)) return lob_free(outer); // copy in the ephemeral public key memcpy(outer->body, remote->ecomp, uECC_BYTES+1); // get the shared secret to create the iv+key for the open aes if(!uECC_shared_secret(remote->key, remote->esecret, shared)) return lob_free(outer); e3x_hash(shared,uECC_BYTES,hash); fold1(hash,hash); memset(iv,0,16); memcpy(iv,&(remote->seq),4); remote->seq++; // increment seq after every use memcpy(outer->body+21,iv,4); // send along the used IV // encrypt the inner into the outer aes_128_ctr(hash,inner_len,iv,lob_raw(inner),outer->body+21+4); // generate secret for hmac if(!uECC_shared_secret(remote->key, local->secret, shared)) return lob_free(outer); memcpy(shared+uECC_BYTES,outer->body+21,4); // use the IV too hmac_256(shared,uECC_BYTES+4,outer->body,21+4+inner_len,hash); fold3(hash,outer->body+21+4+inner_len); // write into last 4 bytes return outer; }
packet_t crypt_delineize_1a(crypt_t c, packet_t p) { packet_t line; unsigned char iv[16], hmac[32]; crypt_1a_t cs = (crypt_1a_t)c->cs; memset(iv,0,16); memcpy(iv+12,p->body+16+4,4); hmac_256(cs->keyIn,16,p->body+16+4,p->body_len-(16+4),hmac); fold3(hmac,hmac); if(memcmp(hmac,p->body+16,4) != 0) return packet_free(p); aes_128_ctr(cs->keyIn,p->body_len-(16+4+4),iv,p->body+16+4+4,p->body+16+4+4); line = packet_parse(p->body+16+4+4, p->body_len-(16+4+4)); packet_free(p); return line; }
packet_t crypt_lineize_1a(crypt_t c, packet_t p) { packet_t line; unsigned char iv[16], hmac[32]; crypt_1a_t cs = (crypt_1a_t)c->cs; line = packet_chain(p); packet_body(line,NULL,16+4+4+packet_len(p)); memcpy(line->body,c->lineIn,16); memcpy(line->body+16+4,&(cs->seq),4); memset(iv,0,16); memcpy(iv+12,&(cs->seq),4); cs->seq++; aes_128_ctr(cs->keyOut,packet_len(p),iv,packet_raw(p),line->body+16+4+4); hmac_256(cs->keyOut,16,line->body+16+4,4+packet_len(p),hmac); fold3(hmac,line->body+16); return line; }
lob_t ephemeral_decrypt(ephemeral_t ephem, lob_t outer) { uint8_t iv[16], hmac[32]; memset(iv,0,16); memcpy(iv,outer->body+16,4); memcpy(hmac,ephem->deckey,16); memcpy(hmac+16,iv,4); // mac just the ciphertext hmac_256(hmac,16+4,outer->body+16+4,outer->body_len-(4+16+4),hmac); fold3(hmac,hmac); if(util_ct_memcmp(hmac,outer->body+(outer->body_len-4),4) != 0) return LOG("hmac failed"); // decrypt in place aes_128_ctr(ephem->deckey,outer->body_len-(16+4+4),iv,outer->body+16+4,outer->body+16+4); // return parse attempt return lob_parse(outer->body+16+4, outer->body_len-(16+4+4)); }
packet_t crypt_deopenize_1a(crypt_t self, packet_t open) { unsigned char secret[uECC_BYTES], iv[16], b64[uECC_BYTES*2*2], hash[32]; packet_t inner, tmp; crypt_1a_t cs = (crypt_1a_t)self->cs; if(open->body_len <= (4+40)) return NULL; inner = packet_new(); if(!packet_body(inner,NULL,open->body_len-(4+40))) return packet_free(inner); // get the shared secret to create the iv+key for the open aes if(!uECC_shared_secret(open->body+4, cs->id_private, secret)) return packet_free(inner); crypt_hash(secret,uECC_BYTES,hash); fold1(hash,hash); memset(iv,0,16); iv[15] = 1; // decrypt the inner aes_128_ctr(hash,inner->body_len,iv,open->body+4+40,inner->body); // load inner packet if((tmp = packet_parse(inner->body,inner->body_len)) == NULL) return packet_free(inner); packet_free(inner); inner = tmp; // generate secret for hmac if(inner->body_len != uECC_BYTES*2) return packet_free(inner); if(!uECC_shared_secret(inner->body, cs->id_private, secret)) return packet_free(inner); // verify hmac_256(secret,uECC_BYTES,open->body+4,open->body_len-4,hash); fold3(hash,hash); if(memcmp(hash,open->body,4) != 0) return packet_free(inner); // stash the hex line key w/ the inner util_hex(open->body+4,40,b64); packet_set_str(inner,"ecc",(char*)b64); return inner; }
uint8_t remote_verify(remote_t remote, local_t local, lob_t outer) { uint8_t shared[uECC_BYTES+4], hash[32]; if(!remote || !local || !outer) return 1; if(outer->head_len != 1 || outer->head[0] != 0x1a) return 2; // generate the key for the hmac, combining the shared secret and IV if(!uECC_shared_secret(remote->key, local->secret, shared)) return 3; memcpy(shared+uECC_BYTES,outer->body+21,4); // verify hmac_256(shared,uECC_BYTES+4,outer->body,outer->body_len-4,hash); fold3(hash,hash); if(util_ct_memcmp(hash,outer->body+(outer->body_len-4),4) != 0) { LOG("hmac failed"); return 4; } return 0; }
void ConvNet::learn(dmatrix3 &stimulus, dvec &target) { dvec result(target.size()); result = feedforward(stimulus); real er = 0; for(int x=0;x<target.size();x++) { L4.Errors[x] = sigmoid_p(target[x]) * (target[x] - result[x]); er += L4.Errors[x]; } std::cout << "Output error: " << er << std::endl; L3.Errors = L4.backpropagation(); dvec l2er = L3.backpropagation(); L2.Errors = fold3(l2er, L2.OutShape); L1.Errors = L2.backpropagation(); L4.weight_update(L3.Activations); L3.weight_update(flatten(L2.Activations)); //L2 is a PoolLayer, those doesn't have any weights. L1.weight_update(Inputs); // Warning: Input is a pointer!!! }