void more_functions() { // You can use most of the <cmath> functions on the variables // note that f is constexpr even though std::pow isn't. constexpr auto f = pow(x, y); // Deriving f is constexpr too, and we get y*pow(x, y-1). constexpr auto dfdx = derive(f, x); // You can print functions out simply with operator<<, to check the result std::cout << "derive(" << f << ", " << x << ") = " << dfdx << "\n\n"; // The evaluation of <cmath> functions are done run-time. double value = dfdx(x=2, y=3); ASSERT_EQUALS(value, 3*pow(2, 3-1)); // You can build up arbitrarily complex expressions. constexpr auto g = atan2(pow(abs(y+x), pow(sqrt(abs(sinh(x)+2)), 2.3)), sin(x)/x); // The derivation is still constexpr, but it returns a rather nasty function. constexpr auto dgdy = derive(g, y); // Try guessing the output :D std::cout << "derive(" << g << ", " << y << ") = " << dgdy << "\n\n"; // The list of the supported functions: // +, -, *, /, abs, fabs, exp, log, log10, pow, sqrt, // sin, cos, tan, sinh, cosh, tanh, asin, acos, atan, atan2 }
int main(){ // test de : echange int a=0, b = 1; printf("%d & %d \n", a, b); echange(&a, &b); printf("%d & %d \n \n", a, b); // test de : derive polypoint P2, D2, C2; double tab[]={2, 6, 7, 3, 0, 1, 5, 0, 8, 9, 9, 1}; int i; P2 = (poly *) malloc (sizeof(poly)); P2->deg=11; for (i=0;i <= P2->deg;i++){ P2->coef[i] = tab[i]; } D2 = derive(P2); dispoly(P2); dispoly(D2); C2 = derive(D2); while(C2->deg >= 1){ C2 = derive(C2); dispoly(C2); } return 0; }
/** * Constructor * @param n polynom degree * @param coeff polynom coefficient from highest degree */ Polynom(int n, double *coeff) { BNB_ASSERT(n >= 3); setDim(1); mN = n; mF = (double*)malloc((n + 1) * sizeof(double)); mDF = (double*)malloc((n + 1) * sizeof(double)); mDDF = (double*)malloc((n + 1) * sizeof(double)); mDDDF = (double*)malloc((n + 1) * sizeof(double)); for(int i = 0; i <= n; i ++) { mF[i] = coeff[i]; } derive(n, mF, mDF); derive(n - 1, mDF, mDDF); derive(n - 2, mDDF, mDDDF); printf("\nDF: "); for(int i = 0; i <= (n - 1); i ++) printf("%lf ", mDF[i]); printf("\nDDF: "); for(int i = 0; i <= (n - 2); i ++) printf("%lf ", mDDF[i]); printf("\nDDDF: "); for(int i = 0; i <= (n - 3); i ++) printf("%lf ", mDDDF[i]); }
/* ============= idODE_RK4::Evaluate ============= */ float idODE_RK4::Evaluate( const float *state, float *newState, float t0, float t1 ) { double delta, halfDelta, sixthDelta; int i; delta = t1 - t0; halfDelta = delta * 0.5; // first step derive( t0, userData, state, d1 ); for ( i = 0; i < dimension; i++ ) { tmpState[i] = state[i] + halfDelta * d1[i]; } // second step derive( t0 + halfDelta, userData, tmpState, d2 ); for ( i = 0; i < dimension; i++ ) { tmpState[i] = state[i] + halfDelta * d2[i]; } // third step derive( t0 + halfDelta, userData, tmpState, d3 ); for ( i = 0; i < dimension; i++ ) { tmpState[i] = state[i] + delta * d3[i]; } // fourth step derive( t0 + delta, userData, tmpState, d4 ); sixthDelta = delta * (1.0/6.0); for ( i = 0; i < dimension; i++ ) { newState[i] = state[i] + sixthDelta * (d1[i] + 2.0 * (d2[i] + d3[i]) + d4[i]); } return delta; }
/** AES-CM key derivation test vectors */ static void test_derivation (void) { static const uint8_t key[16] = "\xE1\xF9\x7A\x0D\x3E\x01\x8B\xE0\xD6\x4F\xA3\x2C\x06\xDE\x41\x39"; static const uint8_t salt[14] = "\x0E\xC6\x75\xAD\x49\x8A\xFE\xEB\xB6\x96\x0B\x3A\xAB\xE6"; static const uint8_t good_cipher[16] = "\xC6\x1E\x7A\x93\x74\x4F\x39\xEE\x10\x73\x4A\xFE\x3F\xF7\xA0\x87"; static const uint8_t good_salt[14] = "\x30\xCB\xBC\x08\x86\x3D\x8C\x85\xD4\x9D\xB3\x4A\x9A\xE1"; static const uint8_t good_auth[94] = "\xCE\xBE\x32\x1F\x6F\xF7\x71\x6B\x6F\xD4\xAB\x49\xAF\x25\x6A\x15" "\x6D\x38\xBA\xA4\x8F\x0A\x0A\xCF\x3C\x34\xE2\x35\x9E\x6C\xDB\xCE" "\xE0\x49\x64\x6C\x43\xD9\x32\x7A\xD1\x75\x57\x8E\xF7\x22\x70\x98" "\x63\x71\xC1\x0C\x9A\x36\x9A\xC2\xF9\x4A\x8C\x5F\xBC\xDD\xDC\x25" "\x6D\x6E\x91\x9A\x48\xB6\x10\xEF\x17\xC2\x04\x1E\x47\x40\x35\x76" "\x6B\x68\x64\x2C\x59\xBB\xFC\x2F\x34\xDB\x60\xDB\xDF\xB2"; static const uint8_t r[6] = { 0, 0, 0, 0, 0, 0 }; gcry_cipher_hd_t prf; uint8_t out[94]; puts ("AES-CM key derivation test..."); printf (" master key: "); printhex (key, sizeof (key)); printf (" master salt: "); printhex (salt, sizeof (salt)); if (gcry_cipher_open (&prf, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CTR, 0) || gcry_cipher_setkey (prf, key, sizeof (key))) fatal ("Internal PRF error"); if (derive (prf, salt, r, sizeof (r), SRTP_CRYPT, out, 16)) fatal ("Internal cipher derivation error"); printf (" cipher key: "); printhex (out, 16); if (memcmp (out, good_cipher, 16)) fatal ("Test failed"); if (derive (prf, salt, r, sizeof (r), SRTP_SALT, out, 14)) fatal ("Internal salt derivation error"); printf (" cipher salt: "); printhex (out, 14); if (memcmp (out, good_salt, 14)) fatal ("Test failed"); if (derive (prf, salt, r, sizeof (r), SRTP_AUTH, out, 94)) fatal ("Internal auth key derivation error"); printf (" auth key: "); printhex (out, 94); if (memcmp (out, good_auth, 94)) fatal ("Test failed"); gcry_cipher_close (prf); }
void higher_level_derivatives() { constexpr auto f = x*x*x; // You can calculate the nth derivate using n nested derive() calls. STATIC_ASSERT_EQUALS(derive(derive(derive(f, x), x), x), 6); // This might be tedious, and hard to read, so // there's a "syntactic sugar" for this operation. STATIC_ASSERT_EQUALS((derive<3>(f, x)), 6); STATIC_ASSERT_EQUALS(derive<50>(f, x), 0); }
void derivation() { AUTO_DERIVE_VARIABLE(int, x); constexpr auto f = x+2; // You can derive an f function according to the x variable using derive(f, x). // In this simple case the derivative of x+2 is simply one. STATIC_ASSERT_EQUALS(derive(f, x), 1); // You can derive the function according to other variables too. AUTO_DERIVE_VARIABLE(int, y); STATIC_ASSERT_EQUALS(derive(f, y), 0); }
void more_about_derivation() { constexpr auto f = x*x; // The derivative of a function might be a function too. constexpr auto dfdx = derive(f, x); // The derivative of x*x is 2*x of course. STATIC_ASSERT_EQUALS(dfdx(x=42), 84); // Since dfdx is a function it can be derived again, and that will result 2. STATIC_ASSERT_EQUALS(derive(dfdx, x), 2); }
QByteArray QCNG::deriveConcatKDF(const QByteArray &publicKey, const QString &digest, int keySize, const QByteArray &algorithmID, const QByteArray &partyUInfo, const QByteArray &partyVInfo) const { d->err = PinUnknown; QByteArray derived; NCRYPT_PROV_HANDLE prov = 0; if(NCryptOpenStorageProvider(&prov, LPCWSTR(d->selected.provider.utf16()), 0)) return derived; NCRYPT_KEY_HANDLE key = 0; if(NCryptOpenKey(prov, &key, LPWSTR(d->selected.key.utf16()), d->selected.spec, 0)) { NCryptFreeObject(prov); return derived; } int err = derive(prov, key, publicKey, digest, keySize, algorithmID, partyUInfo, partyVInfo, derived); NCryptFreeObject(key); switch(err) { case ERROR_SUCCESS: d->err = PinOK; return derived; case SCARD_W_CANCELLED_BY_USER: d->err = PinCanceled; default: return derived; } }
void startProgram() { // Set up the variables int degree = 0, *coefficients = NULL; // Ask the user to input the maximum degree of the polynomial printf("Please enter the maximum degree of the polynomial: "); scanf("%d", °ree); // Allocate the required memory for the coefficients coefficients = (int*) calloc (degree+1, sizeof(int)); // Let the user know if there was a memory allocation error (&terminate the program)... if(coefficients == NULL) { printf("Wooops! There was a memory allocation error. The monkeys are working on it..."); return; } // ...otherwise get on with the program else { // If the degree is negative if(degree<0) { return; } // Ask the user to input the coefficients (can be white-space or newline delimited) printf("Please enter the coefficients: "); // Allow user input so that the number of coefficients is equal to the maximum degree for(int i=0; i<=degree; i++) { scanf("%d", &coefficients[i]); } // Start processing the output printf("The polynomial is "); // First we print the polynomial printPolynomial(1, coefficients, degree, 0); // Then we let the user know we will print the derivative printf("\nIts derivative is "); // Now we derive derive(1, coefficients, degree, 0); // Free the memory free(coefficients); // Clear the address that was pointed to coefficients = NULL; // Clear the input buffer in case the user entered too many coefficients int ch; while ((ch = getchar()) != EOF && ch != '\n') ; /* Code seen and borrowed from http://www.dreamincode.net/forums/topic/89633-input-buffer-problems-with-scanf/page__view__findpost__p__557060 */ // Finally we rerun the program startProgram(); } }
string countAndSay(int n) { string strs[2] = {"1"}; int input = 0; while (--n > 0) { int output = 1 - input; derive(strs[output], strs[input]); input = output; } return strs[input]; }
void simplifications() { // Printing a function to an ostream tells you exactly // which operations will be done when you evaluate it. // If you apply a derivation rule to a function the result often holds parts // like adding zero or multiplying with one. These parts get optimized out // compile-time, so they are not actually evaluated. For ex. the derivative // of a pow against two different variables yields two different functions, // but they were calculated using the same derivation rule. PRINT_NAME_AND_VALUE(derive(pow(x, y), x)); // pow(x, y-1)*y PRINT_NAME_AND_VALUE(derive(pow(x, y), y)); // pow(x, y)*log(x) // These are the results of simplifying the following statement: // pow(f, g) * derive(g, v) * log(f) + pow(f, g-1) * g * derive(f, v) // However be prepared that the even the simplified forms usually // differ from how a human would derive that function. // For example derive(x*x*x, x) is x*x+x*(x+x), not 3*x^2 PRINT_NAME_AND_VALUE(derive(x*x*x, x)); }
/* ============= idODE_Midpoint::~Evaluate ============= */ float idODE_Midpoint::Evaluate( const float *state, float *newState, float t0, float t1 ) { double delta, halfDelta; int i; delta = t1 - t0; halfDelta = delta * 0.5; // first step derive( t0, userData, state, derivatives ); for ( i = 0; i < dimension; i++ ) { tmpState[i] = state[i] + halfDelta * derivatives[i]; } // second step derive( t0 + halfDelta, userData, tmpState, derivatives ); for ( i = 0; i < dimension; i++ ) { newState[i] = state[i] + delta * derivatives[i]; } return delta; }
bessel newton_raphson(double epsilon, bessel j) { while (fabs(j.val) > epsilon) { // get new bessel function for x_(i+1) double y = j.val / derive(j).val; j = j_l(j.l, j.x - y); } return j; }
/* ============= idODE_Euler::Evaluate ============= */ float idODE_Euler::Evaluate( const float *state, float *newState, float t0, float t1 ) { float delta; int i; derive( t0, userData, state, derivatives ); delta = t1 - t0; for ( i = 0; i < dimension; i++ ) { newState[i] = state[i] + delta * derivatives[i]; } return delta; }
int main(){ double(*p) (double); double alpha ; p = &f44; FILE *fp1,*fp2; fp1 = fopen("mdd.txt", "w"); if ( fp1 == NULL ) { printf("Cann't open file\n"); return 1; } for(alpha=1e6;alpha<1e10;alpha*=1.05) { printf("%le \t%le\n",log10(alpha),(derive(p, alpha))); fprintf(fp1,"%le \t%le\n",log10(alpha),(derive(p, alpha))); // printf("%le\n", derive(p, 1e6)); } fclose (fp1); return 0; }
void integers() { // By default, integral constants in function expressions are promoted into // doubles. So the following functions are equivalent. constexpr auto f = atan2(y-x/2, x*y); constexpr auto g = atan2(y-x/2.0, x*y); ASSERT_EQUALS(derive(f, x)(x=1, y=2), -0.64); ASSERT_EQUALS(derive(g, x)(x=1, y=2), -0.64); // You can turn this off with the following macro (before including auto_derive): // #define AUTO_DERIVE_PROMOTE_INTEGRAL_CONSTANTS 0 // But note, that after this, derive(f, x) will contain some integer divisions, // so it won't be equal to derive(g, x). The result of this is usually // disastrous, but sometimes it might be wanted. If the promotion is // turned on, you can use auto_derive::Constant<int> to explicitly create an // integer constant. constexpr auto f2 = atan2(y-x/auto_derive::Constant<int>(2), x*y); constexpr auto g2 = atan2(y-x/auto_derive::Constant<double>(2), x*y); ASSERT_EQUALS(derive(f2, x)(x=1, y=2), -0.48); ASSERT_EQUALS(derive(g2, x)(x=1, y=2), -0.64); }
ast::rvalues operator () (ast::intrinsic const _intrinsic, ast::rvalues && _arguments) const { assert((_arguments.size() != 1) || (_arguments.back().which() != index< ast::rvalue, ast::rvalue_list >)); ast::rvalues results_ = derive(_intrinsic, std::move(_arguments)); if (results_.empty()) { // TODO: process error here results_.emplace_back(I{_intrinsic, R{std::move(_arguments)}}); } return results_; }
int derive(int start, int* coefficients, int degree, int wasZero) { int *current, previousZero; // If the degree is 0 or 1 the ouput will always be the same switch(degree) { case 0: printf("0\n\n"); return 0; break; case 1: printf("%d\n\n", coefficients[start-1]); return 0; break; } current = &coefficients[start-1]; // Modifiy the coefficient for its derivative *current *= degree - start + 1; // Let's start pretty printing. Firstly we make sure it isn't 0 if(*current != 0) { // Run the makePretty function makePretty(degree-1, wasZero, start, *current); // We then decide whether to output an x if(start < degree - 1) { printf("x^%d", (degree - start)); } // If we're on the final degree of the polynomial we omit the power (^1) if(start == degree - 1) { putchar('x'); } // This coefficient isn't 0, so we pass that in the function previousZero = 0; } else { // This coefficient is 0, so we pass that in the function previousZero = 1; } // If there are still coefficients to print we re-run the function if(start<degree) { derive(start + 1, coefficients, degree, previousZero); // Otherwise we add some new-lines and restart the program } else { printf("\n\n"); } return 0; }
static bool alg_wrap_unw(const jose_hook_alg_t *alg, jose_cfg_t *cfg, const json_t *jwe, const json_t *rcp, const json_t *jwk, json_t *cek) { const json_t *epk = NULL; json_auto_t *exc = NULL; json_auto_t *der = NULL; json_auto_t *hdr = NULL; const char *wrap = NULL; hdr = jose_jwe_hdr(jwe, rcp); epk = json_object_get(hdr, "epk"); if (!hdr || !epk) return false; /* If the JWK has a private key, perform the normal exchange. */ if (json_object_get(jwk, "d")) { const jose_hook_alg_t *ecdh = NULL; ecdh = jose_hook_alg_find(JOSE_HOOK_ALG_KIND_EXCH, "ECDH"); if (!ecdh) return false; exc = ecdh->exch.exc(ecdh, cfg, jwk, epk); /* Otherwise, allow external exchanges. */ } else if (json_equal(json_object_get(jwk, "crv"), json_object_get(epk, "crv"))) { exc = json_deep_copy(jwk); } if (!exc) return false; der = derive(alg, cfg, hdr, cek, exc); if (!der) return false; wrap = strchr(alg->name, '+'); if (wrap) { const jose_hook_alg_t *kw = NULL; kw = jose_hook_alg_find(JOSE_HOOK_ALG_KIND_WRAP, &wrap[1]); if (!kw) return false; return kw->wrap.unw(kw, cfg, jwe, rcp, der, cek); } return json_object_update(cek, der) == 0; }
Real Castro::maxVal (const std::string& name, Real time) { Real maxval = 0.0; const Real* dx = geom.CellSize(); MultiFab* mf = derive(name,time,0); BL_ASSERT(mf != 0); maxval = (*mf).max(0,0); delete mf; return maxval; }
void Profiler::deriveEx(float *data, int rowSize, int colSize) { int i; int j; float *buffer; buffer = new float[colSize]; for (i = 0; i < rowSize; i++) { for (j = 0; j < colSize; j++) buffer[j] = data[j * rowSize + i]; derive(buffer, colSize); for (j = 0; j < colSize; j++) data[j * rowSize + i] = buffer[j]; } delete []buffer; }
void startProgram() { // Set up the variables. As per the specification, we assume that the maximum number of coefficients is 10 int degree = 0, coefficients[MAXDEGREE+1]; // Ask the user to input the maximum degree of the polynomial printf("Please enter the maximum degree of the polynomial: "); scanf("%d", °ree); // If the degree is negative or greater than 10 then we terminate if(degree<0 || degree>MAXDEGREE) { return; } // Ask the user to input the coefficients (can be white-space or newline delimited) printf("Please enter the coefficients: "); // Allow user input so that the number of coefficients is equal to the maximum degree for(int i=0; i<=degree; i++) { scanf("%d", &coefficients[i]); } // Start processing the output printf("The polynomial is "); // First we print the polynomial printPolynomial(1, coefficients, degree, 0); // Then we let the user know we will print the derivative printf("\nIts derivative is "); // Now we derive derive(1, coefficients, degree, 0); // Clear the input buffer in case the user entered too many coefficients int ch; while ((ch = getchar()) != EOF && ch != '\n') ; /* Code seen and borrowed from http://www.dreamincode.net/forums/topic/89633-input-buffer-problems-with-scanf/page__view__findpost__p__557060 */ // Finally we rerun the program startProgram(); }
void complex_variables() { using Complex = std::complex<double>; // You can use the auto_derive library to derive complex functions too. AUTO_DERIVE_VARIABLE(Complex, x); constexpr auto f = asin(cosh(x)); ASSERT_EQUALS(f(x=0.3), (Complex{1.5708, 0.3})); Complex dfdx_val = derive(f, x)(x=0.5), i{0, 1}; // dfdx_val is sqrt(-1), which is matematically +i AND -i. // The result will be one of these two. Note that // std::sqrt({-1, +0}) is +i, but std::sqrt({-1, -0}) is -i, // so the actual result depends on the computational accuracy. assert(equals(dfdx_val, i) || equals(dfdx_val, -i)); // Basically this library works on any user-defined type, as long as it has // the required function overloads for the used operators. }
friend constexpr auto derive(Atan2 const& self, Variable v) { // At the points where the derivative exists, atan2(y, x) is, // except for a constant, equal to atan(y/x). return derive(atan(self.lhs() / self.rhs()), v); }
int main(int argc, char** argv) { char* secret; char* secret_check; char* domain; char* output; int c; scrypt_state_t state; state.n = kDeriveScryptN; state.r = kDeriveScryptR; state.p = kDeriveScryptP; domain = NULL; do { c = getopt_long(argc, argv, long_flags, long_options, NULL); switch (c) { case 'v': print_version(); exit(0); break; case 'd': domain = optarg; break; case 'n': case 'r': case 'p': { int val; val = atoi(optarg); if (c == 'n') state.n = val; else if (c == 'r') state.r = val; else state.p = val; break; } default: if (domain != NULL) break; print_help(argc, argv); exit(0); break; } } while (c != -1); secret = strdup(getpass("Secret: ")); secret_check = strdup(getpass("Secret (just checking): ")); if (strcmp(secret, secret_check) != 0) { memset(secret, 0, strlen(secret)); memset(secret_check, 0, strlen(secret_check)); fprintf(stderr, "Secrets do not match\n"); return 1; } memset(secret_check, 0, strlen(secret_check)); free(secret_check); output = derive(&state, secret, domain); memset(secret, 0, strlen(secret)); assert(output != NULL); fprintf(stdout, "%s\n", output); free(secret); free(output); return 0; }
/* ============= idODE_RK4Adaptive::Evaluate ============= */ float idODE_RK4Adaptive::Evaluate( const float *state, float *newState, float t0, float t1 ) { double delta, halfDelta, fourthDelta, sixthDelta; double error, max; int i, n; delta = t1 - t0; for ( n = 0; n < 4; n++ ) { halfDelta = delta * 0.5; fourthDelta = delta * 0.25; // first step of first half delta derive( t0, userData, state, d1 ); for ( i = 0; i < dimension; i++ ) { tmpState[i] = state[i] + fourthDelta * d1[i]; } // second step of first half delta derive( t0 + fourthDelta, userData, tmpState, d2 ); for ( i = 0; i < dimension; i++ ) { tmpState[i] = state[i] + fourthDelta * d2[i]; } // third step of first half delta derive( t0 + fourthDelta, userData, tmpState, d3 ); for ( i = 0; i < dimension; i++ ) { tmpState[i] = state[i] + halfDelta * d3[i]; } // fourth step of first half delta derive( t0 + halfDelta, userData, tmpState, d4 ); sixthDelta = halfDelta * (1.0/6.0); for ( i = 0; i < dimension; i++ ) { tmpState[i] = state[i] + sixthDelta * (d1[i] + 2.0 * (d2[i] + d3[i]) + d4[i]); } // first step of second half delta derive( t0 + halfDelta, userData, tmpState, d1half ); for ( i = 0; i < dimension; i++ ) { tmpState[i] = state[i] + fourthDelta * d1half[i]; } // second step of second half delta derive( t0 + halfDelta + fourthDelta, userData, tmpState, d2 ); for ( i = 0; i < dimension; i++ ) { tmpState[i] = state[i] + fourthDelta * d2[i]; } // third step of second half delta derive( t0 + halfDelta + fourthDelta, userData, tmpState, d3 ); for ( i = 0; i < dimension; i++ ) { tmpState[i] = state[i] + halfDelta * d3[i]; } // fourth step of second half delta derive( t0 + delta, userData, tmpState, d4 ); sixthDelta = halfDelta * (1.0/6.0); for ( i = 0; i < dimension; i++ ) { newState[i] = state[i] + sixthDelta * (d1[i] + 2.0 * (d2[i] + d3[i]) + d4[i]); } // first step of full delta for ( i = 0; i < dimension; i++ ) { tmpState[i] = state[i] + halfDelta * d1[i]; } // second step of full delta derive( t0 + halfDelta, userData, tmpState, d2 ); for ( i = 0; i < dimension; i++ ) { tmpState[i] = state[i] + halfDelta * d2[i]; } // third step of full delta derive( t0 + halfDelta, userData, tmpState, d3 ); for ( i = 0; i < dimension; i++ ) { tmpState[i] = state[i] + delta * d3[i]; } // fourth step of full delta derive( t0 + delta, userData, tmpState, d4 ); sixthDelta = delta * (1.0/6.0); for ( i = 0; i < dimension; i++ ) { tmpState[i] = state[i] + sixthDelta * (d1[i] + 2.0 * (d2[i] + d3[i]) + d4[i]); } // get max estimated error max = 0.0; for ( i = 0; i < dimension; i++ ) { error = idMath::Fabs( (newState[i] - tmpState[i]) / (delta * d1[i] + 1e-10) ); if ( error > max ) { max = error; } } error = max / maxError; if ( error <= 1.0f ) { return delta * 4.0; } if ( delta <= 1e-7 ) { return delta; } delta *= 0.25; } return delta; }
friend constexpr auto derive(Acos const& self, Variable v) { return -derive(self.expr(), v) / sqrt(1 - square(self.expr())); }
static bool alg_wrap_wrp(const jose_hook_alg_t *alg, jose_cfg_t *cfg, json_t *jwe, json_t *rcp, const json_t *jwk, json_t *cek) { const jose_hook_alg_t *ecdh = NULL; json_auto_t *exc = NULL; json_auto_t *hdr = NULL; json_auto_t *epk = NULL; json_auto_t *der = NULL; const char *wrap = NULL; json_t *h = NULL; if (json_object_get(cek, "k")) { if (strcmp(alg->name, "ECDH-ES") == 0) return false; } else if (!jose_jwk_gen(cfg, cek)) { return false; } hdr = jose_jwe_hdr(jwe, rcp); if (!hdr) return false; h = json_object_get(rcp, "header"); if (!h && json_object_set_new(rcp, "header", h = json_object()) == -1) return false; epk = json_pack("{s:s,s:O}", "kty", "EC", "crv", json_object_get(jwk, "crv")); if (!epk) return false; if (!jose_jwk_gen(cfg, epk)) return false; ecdh = jose_hook_alg_find(JOSE_HOOK_ALG_KIND_EXCH, "ECDH"); if (!ecdh) return false; exc = ecdh->exch.exc(ecdh, cfg, epk, jwk); if (!exc) return false; if (!jose_jwk_pub(cfg, epk)) return false; if (json_object_set(h, "epk", epk) == -1) return false; der = derive(alg, cfg, hdr, cek, exc); if (!der) return false; wrap = strchr(alg->name, '+'); if (wrap) { const jose_hook_alg_t *kw = NULL; kw = jose_hook_alg_find(JOSE_HOOK_ALG_KIND_WRAP, &wrap[1]); if (!kw) return false; return kw->wrap.wrp(kw, cfg, jwe, rcp, der, cek); } if (json_object_update(cek, der) < 0) return false; return add_entity(jwe, rcp, "recipients", "header", "encrypted_key", NULL); }